// Copyright 2023 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::digest::ExpectedDigest;
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>,
    pub digest: Option<ExpectedDigest>,
}

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

#[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);
                        }
                    }
                }

                let digest = match variant.digest {
                    Some(s) => Some(s.parse()?),
                    None => None,
                };

                Ok(DownloadVariant {
                    matches: variant_match,
                    url_parameters: variant.url_parameters,
                    digest,
                })
            })
            .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),
        };

        let digest = match value.digest {
            Some(s) => Some(s.parse()?),
            None => None,
        };

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

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()),
                    digest: 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(), 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()),
                    digest: 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(), 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()),
                    digest: None,
                },
            )),
        };
        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()),
                    digest: None,
                },
            )),
        };
        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()),
                    digest: None,
                },
            )),
        };
        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);
    }
}
