// Copyright 2022 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf};

use crate::project::manifest;
use crate::util::StringSub;
use crate::{download, platform, Error, Result};

/// A source of targets.
#[derive(Debug)]
pub struct Provider {
    /// The globally-unique name of the provider.
    pub name: String,

    /// Manifest file in which the provider is defined.
    pub file: PathBuf,

    /// If true, targets provided by the provider appear in the global namespace
    /// instead of nested under the provider's name.
    pub global: bool,
}

impl Provider {
    #[must_use]
    pub(crate) fn new(name: &str, file: &Path, global: bool) -> Self {
        Self {
            name: name.into(),
            file: file.into(),
            global,
        }
    }
}

/// A buildable `qg` target.
#[derive(Debug)]
pub struct Target {
    /// The target's name, without a provider namespace.
    name: String,

    /// The name of the target's provider.
    provider: String,

    /// Whether the target lives in the global namespace.
    global: bool,

    /// List of targets on which this one depends, storing their full namespaced
    /// paths.
    dependencies: Vec<String>,

    /// Information about how to build the target, specific to a type of
    /// provider.
    metadata: Metadata,
}

/// Additional information about how to build a target specific to a type
/// of provider.
#[derive(Debug)]
pub enum Metadata {
    DepOnly,
    Cipd(Cipd),
    Download(Download),

    #[cfg(test)]
    Fake(Fake),
}

#[derive(Debug)]
pub struct Cipd {
    pub path: String,
    pub platforms: Vec<String>,
    pub tags: Vec<String>,
    pub subdir: Option<PathBuf>,
}

impl From<manifest::CipdPackage> for Cipd {
    fn from(value: manifest::CipdPackage) -> Self {
        // TODO(frolv): This should do some verification.
        Self {
            path: value.path,
            platforms: value.platforms,
            tags: value.tags,
            subdir: value.subdir,
        }
    }
}

#[derive(Debug)]
pub struct Download {
    pub format: download::Format,
    pub url: StringSub,
    pub url_parameters: HashMap<String, String>,
    pub variants: Vec<DownloadVariant>,
}

#[derive(Debug)]
pub struct DownloadVariant {
    pub matches: VariantMatch,
    url_parameters: HashMap<String, String>,
}

#[derive(Debug)]
pub struct VariantMatch {
    system: Option<platform::System>,
    arch: Option<platform::Architecture>,
}

impl TryFrom<manifest::DownloadablePackage> for Download {
    type Error = Error;

    fn try_from(value: manifest::DownloadablePackage) -> std::result::Result<Self, Self::Error> {
        let url_parameters = value.url_parameters;
        let mut all_params: HashSet<&str> = url_parameters.keys().map(String::as_str).collect();

        let variants: Vec<DownloadVariant> = value
            .variants
            .into_iter()
            .map(|variant| {
                let mut variant_match = VariantMatch {
                    system: None,
                    arch: None,
                };

                for (var, val) in &variant.match_vars {
                    match var.as_str() {
                        "os" => variant_match.system = Some(val.parse::<platform::System>()?),
                        "arch" => variant_match.arch = Some(val.parse::<platform::Architecture>()?),
                        _ => {
                            // TODO(frolv): Return an error with the invalid variable.
                            return Err(Error::GenericErrorPlaceholder);
                        }
                    }
                }

                Ok(DownloadVariant {
                    matches: variant_match,
                    url_parameters: variant.url_parameters,
                })
            })
            .collect::<Result<Vec<_>>>()?;

        for variant in &variants {
            all_params.extend(variant.url_parameters.keys().map(String::as_str));
        }

        // Check if any of the parameters specified in the `url_parameters`
        // mapping have invalid names.
        let invalid_vars: Vec<_> = all_params
            .iter()
            .filter(|&&param| !StringSub::valid_variable_name(param))
            .collect();
        if !invalid_vars.is_empty() {
            // TODO(frolv): Return an error containing the invalid variables.
            println!("invalid URL variable names {invalid_vars:?}");
            return Err(Error::GenericErrorPlaceholder);
        }

        // Next, check the URL string itself. Each parameter substitution
        // defined within braces should exist within a provided `url_parameters`
        // mapping.
        let url: StringSub = value.url.parse()?;

        let missing_vars: Vec<_> = url.vars().filter(|&v| !all_params.contains(v)).collect();
        if !missing_vars.is_empty() {
            // TODO(frolv): Return an error containing the missing variables.
            println!("missing URL parameters {missing_vars:?}");
            return Err(Error::GenericErrorPlaceholder);
        }

        let format = match value.format.ok_or(Error::GenericErrorPlaceholder)?.as_str() {
            "bin" => {
                download::Format::Binary(value.bin_name.ok_or(Error::GenericErrorPlaceholder)?)
            }
            _ => return Err(Error::GenericErrorPlaceholder),
        };

        Ok(Self {
            format,
            url,
            url_parameters,
            variants,
        })
    }
}

impl TryFrom<manifest::TargetType> for Metadata {
    type Error = Error;

    fn try_from(value: manifest::TargetType) -> std::result::Result<Self, Self::Error> {
        match value {
            manifest::TargetType::Cipd(data) => Ok(Self::Cipd(data.into())),
            manifest::TargetType::Download(data) => data.try_into().map(Self::Download),
            #[cfg(test)]
            manifest::TargetType::Fake(data) => Ok(Self::Fake(data.into())),
        }
    }
}

impl Target {
    pub(crate) fn from_manifest(
        name: &str,
        provider: &str,
        global: bool,
        target: manifest::Target,
    ) -> Result<Self> {
        let target = Self {
            name: name.to_owned(),
            provider: provider.to_owned(),
            global,
            dependencies: target.deps,
            metadata: target
                .desc
                .map_or(Ok(Metadata::DepOnly), Metadata::try_from)?,
        };

        Ok(target)
    }

    /// Returns the name of the package.
    #[must_use]
    pub fn name(&self) -> &str {
        &self.name
    }

    /// Returns the name of the package's provider.
    #[must_use]
    pub fn provider(&self) -> &str {
        &self.provider
    }

    /// Returns true if the target is defined in the global namespace.
    #[must_use]
    pub fn is_global(&self) -> bool {
        self.global
    }

    /// Returns the package's dependencies.
    pub fn dependencies(&self) -> impl ExactSizeIterator<Item = &str> {
        self.dependencies.iter().map(String::as_str)
    }

    /// Returns the fully-qualified name of the target.
    #[must_use]
    pub fn full_name(&self) -> String {
        if self.global {
            self.name.clone()
        } else {
            format!("{}:{}", self.provider, self.name)
        }
    }

    /// Returns the type of the package as a string.
    #[must_use]
    pub fn type_string(&self) -> &str {
        match self.metadata {
            Metadata::DepOnly => "dep_only",
            Metadata::Cipd(_) => "cipd",
            Metadata::Download(_) => "download",

            #[cfg(test)]
            Metadata::Fake(_) => "fake",
        }
    }

    /// Returns the metadata of the target
    #[must_use]
    pub fn metadata(&self) -> &Metadata {
        &self.metadata
    }
}

#[derive(Debug)]
#[cfg(test)]
pub struct Fake {
    pub duration_ticks: u32,
}

#[cfg(test)]
impl From<manifest::FakeTarget> for Fake {
    fn from(value: manifest::FakeTarget) -> Self {
        Self {
            duration_ticks: value.duration_ticks,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn target_from_deponly() {
        let manifest_target = manifest::Target {
            namespace: manifest::ProviderNamespace::Local,
            deps: vec!["libqg".into(), "cargo".into()],
            desc: None,
        };
        let target = Target::from_manifest("qg", "qg-provider", true, manifest_target).unwrap();
        assert_eq!(target.name(), "qg");
        assert_eq!(target.provider(), "qg-provider");
        assert_eq!(target.full_name(), "qg");
        assert!(target.is_global());
        assert_eq!(target.dependencies().count(), 2);
        assert_eq!(target.type_string(), "dep_only");
    }

    #[test]
    fn target_from_deponly_local() {
        let manifest_target = manifest::Target {
            namespace: manifest::ProviderNamespace::Local,
            deps: vec!["cargo".into()],
            desc: None,
        };
        let target = Target::from_manifest("qg", "qg-provider", false, manifest_target).unwrap();
        assert_eq!(target.name(), "qg");
        assert_eq!(target.provider(), "qg-provider");
        assert_eq!(target.full_name(), "qg-provider:qg");
        assert!(!target.is_global());
        assert_eq!(target.dependencies().count(), 1);
        assert_eq!(target.type_string(), "dep_only");
    }

    #[test]
    fn target_from_download_basic_valid() {
        let manifest_target = manifest::Target {
            namespace: manifest::ProviderNamespace::Local,
            deps: vec![],
            desc: Some(manifest::TargetType::Download(
                manifest::DownloadablePackage {
                    url: "https://qg.io/client".into(),
                    url_parameters: HashMap::new(),
                    variants: vec![],
                    format: Some("bin".into()),
                    bin_name: Some("qg".into()),
                },
            )),
        };
        let target = Target::from_manifest("qg", "qg-provider", true, manifest_target).unwrap();
        assert_eq!(target.name(), "qg");
        assert_eq!(target.provider(), "qg-provider");
        assert_eq!(target.full_name(), "qg");
        assert!(target.is_global());
        assert_eq!(target.dependencies().count(), 0);
        assert_eq!(target.type_string(), "download");
    }

    #[test]
    fn target_from_download_params_valid() {
        let manifest_target = manifest::Target {
            namespace: manifest::ProviderNamespace::Local,
            deps: vec![],
            desc: Some(manifest::TargetType::Download(
                manifest::DownloadablePackage {
                    url: "https://qg.io/client?version={ver}".into(),
                    url_parameters: HashMap::from([("ver".into(), "1.2.4".into())]),
                    variants: vec![],
                    format: Some("bin".into()),
                    bin_name: Some("qg".into()),
                },
            )),
        };
        let target = Target::from_manifest("qg", "qg-provider", true, manifest_target).unwrap();
        assert_eq!(target.name(), "qg");
        assert_eq!(target.provider(), "qg-provider");
        assert_eq!(target.full_name(), "qg");
        assert!(target.is_global());
        assert_eq!(target.dependencies().count(), 0);
        assert_eq!(target.type_string(), "download");
    }

    #[test]
    fn target_from_download_params_missing() {
        let manifest_target = manifest::Target {
            namespace: manifest::ProviderNamespace::Local,
            deps: vec![],
            desc: Some(manifest::TargetType::Download(
                manifest::DownloadablePackage {
                    url: "https://qg.io/client?version={ver}".into(),
                    url_parameters: HashMap::new(), // no `ver` defined
                    variants: vec![],
                    format: Some("bin".into()),
                    bin_name: Some("qg".into()),
                },
            )),
        };
        let err = Target::from_manifest("qg", "qg-provider", true, manifest_target).unwrap_err();
        assert!(matches!(err, Error::GenericErrorPlaceholder));
    }

    #[test]
    fn target_from_download_params_invalid_name() {
        let manifest_target = manifest::Target {
            namespace: manifest::ProviderNamespace::Local,
            deps: vec![],
            desc: Some(manifest::TargetType::Download(
                manifest::DownloadablePackage {
                    url: "https://qg.io/client?version={0ver}".into(),
                    url_parameters: HashMap::from([("0ver".into(), "01.2.4".into())]),
                    variants: vec![],
                    format: Some("bin".into()),
                    bin_name: Some("qg".into()),
                },
            )),
        };
        let err = Target::from_manifest("qg", "qg-provider", true, manifest_target).unwrap_err();
        assert!(matches!(err, Error::GenericErrorPlaceholder));
    }

    #[test]
    fn target_from_download_params_empty_name() {
        let manifest_target = manifest::Target {
            namespace: manifest::ProviderNamespace::Local,
            deps: vec![],
            desc: Some(manifest::TargetType::Download(
                manifest::DownloadablePackage {
                    url: "https://qg.io/client?version={}".into(),
                    url_parameters: HashMap::new(),
                    variants: vec![],
                    format: Some("bin".into()),
                    bin_name: Some("qg".into()),
                },
            )),
        };
        let err = Target::from_manifest("qg", "qg-provider", true, manifest_target).unwrap_err();
        assert!(matches!(err, Error::GenericErrorPlaceholder));
    }

    #[test]
    fn target_from_fake() {
        let manifest_target = manifest::Target {
            namespace: manifest::ProviderNamespace::Local,
            deps: vec!["a".into(), "b".into()],
            desc: Some(manifest::TargetType::Fake(manifest::FakeTarget {
                duration_ticks: 42,
            })),
        };

        let target =
            Target::from_manifest("qg-fake", "qg-fake-provider", true, manifest_target).unwrap();
        assert_eq!(target.name(), "qg-fake");
        assert_eq!(target.provider(), "qg-fake-provider");
        assert_eq!(target.full_name(), "qg-fake");
        assert!(target.is_global());
        assert_eq!(target.dependencies().count(), 2);
        assert_eq!(target.type_string(), "fake");

        let Metadata::Fake(fake) = target.metadata else {
            panic!("target metadata is not of the Fake type.");
        };

        assert_eq!(fake.duration_ticks, 42);
    }
}
