// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use {
    crate::gn::add_version_suffix,
    crate::types::*,
    camino::{Utf8Path, Utf8PathBuf},
    cargo_metadata::{Package, PackageId, Version},
    std::borrow::Cow,
    std::cmp::Ordering,
    std::collections::{hash_map::DefaultHasher, HashMap},
    std::hash::{Hash, Hasher},
};

pub struct GnTarget<'a> {
    /// Package ID from the Cargo metadata
    cargo_pkg_id: &'a PackageId,
    /// Version of the Package from Cargo
    version: &'a Version,
    /// Name of the target given in Cargo.toml
    pub target_name: &'a str,
    /// Name of the package given in Cargo.toml
    pub pkg_name: &'a str,
    /// Path to the root of the crate
    pub crate_root: &'a Utf8Path,
    /// Rust Edition of the target
    /// rustc: --edition
    pub edition: &'a str,
    /// Type of crate
    /// rustc: --crate-type
    pub target_type: GnRustType,
    /// Rust features enabled on this target
    /// rustc: --cfg=feature=<string>
    pub features: &'a [String],
    /// Target depends on Cargo running a custom build-script
    pub has_build_script: bool,
    /// Target depends on Cargo running a custom build-script
    pub dependencies: HashMap<Option<Platform>, Vec<(&'a Package, String)>>,
}

impl std::fmt::Debug for GnTarget<'_> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let display_name = if self.target_name != self.pkg_name {
            Cow::Owned(format!("{}.{}", self.pkg_name, self.target_name))
        } else {
            Cow::Borrowed(self.pkg_name)
        };
        if self.has_build_script {
            write!(f, "{:?} with custom-build: {}", self.target_type, display_name)
        } else {
            write!(f, "{:?}: {}", self.target_type, display_name)
        }
    }
}

impl PartialEq for GnTarget<'_> {
    fn eq(&self, other: &Self) -> bool {
        self.cargo_pkg_id == other.cargo_pkg_id
            && self.target_name == other.target_name
            && self.target_type == other.target_type
    }
}
impl Eq for GnTarget<'_> {}

impl PartialOrd for GnTarget<'_> {
    fn partial_cmp(&self, other: &GnTarget<'_>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for GnTarget<'_> {
    fn cmp(&self, other: &GnTarget<'_>) -> Ordering {
        self.target_name
            .cmp(other.target_name)
            .then(self.target_type.cmp(&other.target_type))
            .then(self.cargo_pkg_id.cmp(other.cargo_pkg_id))
    }
}

impl Hash for GnTarget<'_> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.cargo_pkg_id.hash(state);
        self.target_name.hash(state);
        self.target_type.hash(state);
    }
}

impl<'a> GnTarget<'a> {
    pub fn new(
        cargo_pkg_id: &'a PackageId,
        target_name: &'a str,
        pkg_name: &'a str,
        edition: &'a str,
        crate_root: &'a Utf8Path,
        version: &'a Version,
        target_type: GnRustType,
        features: &'a [Feature],
        has_build_script: bool,
        dependencies: HashMap<Option<Platform>, Vec<(&'a Package, String)>>,
    ) -> Self {
        GnTarget {
            cargo_pkg_id,
            target_name,
            pkg_name,
            edition,
            crate_root,
            version,
            target_type,
            features,
            has_build_script,
            dependencies,
        }
    }

    /// Name of the target given in Cargo.toml
    pub fn name(&self) -> String {
        self.target_name.to_owned()
    }

    /// Version of the Package from Cargo
    pub fn version(&self) -> String {
        self.version.to_string()
    }

    pub fn metadata_hash(&self) -> String {
        let mut hasher = DefaultHasher::new();
        self.gn_target_name().hash(&mut hasher);
        format!("{:x}", hasher.finish())
    }

    /// with version
    pub fn gn_target_name(&self) -> String {
        let prefix = match self.target_type {
            GnRustType::Library | GnRustType::Rlib | GnRustType::ProcMacro => {
                Cow::Borrowed(self.pkg_name)
            }
            GnRustType::Binary => Cow::Owned(format!("{}-{}", self.pkg_name, self.target_name)),
            ty => panic!("Don't know how to represent this type \"{:?}\" in GN", ty),
        };
        add_version_suffix(&prefix, &self.version)
    }

    pub fn package_root(&self) -> Utf8PathBuf {
        let mut package_root = self.crate_root.canonicalize_utf8().unwrap();

        while !package_root.join("Cargo.toml").exists() {
            package_root = package_root
                .parent()
                .expect("searching up from the crate root we must find a cargo.toml")
                .to_path_buf();
        }

        assert!(
            !package_root.ends_with("third_party/rust_crates"),
            "must find a cargo.toml before the root one"
        );

        package_root.to_owned()
    }

    pub fn gn_target_type(&self) -> String {
        match self.target_type {
            GnRustType::Library | GnRustType::Rlib => String::from("rust_library"),
            GnRustType::Binary => String::from("executable"),
            GnRustType::ProcMacro => String::from("rust_proc_macro"),
            ty => panic!("Don't know how to represent this type \"{:?}\" in GN", ty),
        }
    }
}
