#![cfg_attr(docsrs, doc(include = "../../docs/licenses/cfg.md"))]

use crate::{
    cfg::{deprecated, PackageSpec, ValidationContext},
    diag::{Diagnostic, FileId, Label},
    LintLevel, PathBuf, Span, Spanned,
};
use toml_span::{de_helpers::TableHelper, value::Value, DeserError, Deserialize};

const DEFAULT_CONFIDENCE_THRESHOLD: f32 = 0.8;

/// Allows agreement of licensing terms based on whether the license is
/// [OSI Approved](https://opensource.org/licenses) or [considered free](
/// https://www.gnu.org/licenses/license-list.en.html) by the FSF
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default, strum::VariantArray, strum::VariantNames)]
#[cfg_attr(test, derive(serde::Serialize))]
#[strum(serialize_all = "kebab-case")]
pub enum BlanketAgreement {
    /// The license must be both OSI Approved and FSF/Free Libre
    Both,
    /// The license can be be either OSI Approved or FSF/Free Libre
    Either,
    /// The license must be OSI Approved
    Osi,
    /// The license must be FSF/Free
    Fsf,
    /// The license must be OSI Approved but not FSF/Free Libre
    OsiOnly,
    /// The license must be FSF/Free Libre but not OSI Approved
    FsfOnly,
    /// The license is not regarded specially
    #[default]
    Neither,
}

crate::enum_deser!(BlanketAgreement);

/// Configures how private crates are handled and detected
#[derive(Default)]
#[cfg_attr(test, derive(serde::Serialize))]
pub struct Private {
    /// If enabled, ignores workspace crates that aren't published, or are
    /// only published to private registries
    pub ignore: bool,
    /// One or more URLs to private registries, if a crate comes from one
    /// of these registries, the crate will not have its license checked
    pub ignore_sources: Vec<Spanned<String>>,
    /// One or more private registries that you might publish crates to, if
    /// a crate is only published to private registries, and ignore is true
    /// the crate will not have its license checked
    pub registries: Vec<String>,
}

impl<'de> Deserialize<'de> for Private {
    fn deserialize(value: &mut Value<'de>) -> Result<Self, DeserError> {
        let mut th = TableHelper::new(value)?;

        let ignore = th.optional("ignore").unwrap_or_default();
        let ignore_sources = th.optional("ignore-sources").unwrap_or_default();
        let registries = th.optional("registries").unwrap_or_default();

        th.finalize(None)?;

        Ok(Self {
            ignore,
            ignore_sources,
            registries,
        })
    }
}

/// The path and hash of a LICENSE file
#[derive(PartialEq, Eq)]
#[cfg_attr(test, derive(serde::Serialize))]
pub struct FileSource {
    /// The crate relative path of the LICENSE file
    /// Spanned so we can report typos on it in case it never matches anything.
    pub path: Spanned<PathBuf>,
    /// The hash of the LICENSE text. If the `path`'s hash
    /// differs from the contents of the path, the file is
    /// parsed to determine if the license(s) contained in
    /// it are still the same
    pub hash: u32,
}

impl<'de> Deserialize<'de> for FileSource {
    fn deserialize(value: &mut Value<'de>) -> Result<Self, DeserError> {
        let mut th = TableHelper::new(value)?;

        let path: Spanned<String> = th.required("path")?;
        let hash = th.required("hash")?;

        th.finalize(None)?;

        Ok(Self {
            path: path.map(),
            hash,
        })
    }
}

/// Some crates have complicated LICENSE files that eg contain multiple license
/// texts in a single file, or are otherwise sufficiently different from the
/// canonical license text that the confidence level cargo-deny can attribute to
/// them falls below the `confidence-threshold` you want generally across all
/// license texts. `Clarification`s allow you to manually assign the
/// [SPDX expression](https://spdx.github.io/spdx-spec/appendix-IV-SPDX-license-expressions/)
/// to use for a particular crate as well as 1 or more file sources used as the
/// ground truth for that expression. If the files change in a future version
/// of the crate, the clarification will be ignored and the crate will be checked
/// as normal.
pub struct Clarification {
    /// The package spec the clarification applies to
    pub spec: PackageSpec,
    /// The [SPDX expression](https://spdx.github.io/spdx-spec/appendix-IV-SPDX-license-expressions/)
    /// to apply to the crate.
    pub expression: Spanned<String>,
    /// Files in the crate that are the ground truth for the expression.
    pub license_files: Vec<FileSource>,
}

impl<'de> Deserialize<'de> for Clarification {
    fn deserialize(value: &mut Value<'de>) -> Result<Self, DeserError> {
        let spec = PackageSpec::deserialize(value)?;

        let mut th = TableHelper::new(value)?;

        let expression = th.required("expression")?;
        let license_files = th.required("license-files")?;

        th.finalize(None)?;

        Ok(Self {
            spec,
            expression,
            license_files,
        })
    }
}

/// An exception is a way for 1 or more licenses to be allowed only for a
/// particular crate.
pub struct Exception {
    /// The package spec the exception applies to
    pub spec: PackageSpec,
    /// One or more [SPDX identifiers](https://spdx.org/licenses/) that are
    /// allowed only for this crate.
    pub allow: Vec<Licensee>,
}

impl<'de> Deserialize<'de> for Exception {
    fn deserialize(value: &mut Value<'de>) -> Result<Self, DeserError> {
        let spec = PackageSpec::deserialize(value)?;

        let mut th = TableHelper::new(value)?;
        let allow = th.required("allow")?;

        th.finalize(None)?;

        Ok(Self { spec, allow })
    }
}

#[derive(Debug, PartialEq, Eq, Ord, PartialOrd)]
pub struct Licensee(pub Spanned<spdx::Licensee>);

impl<'de> Deserialize<'de> for Licensee {
    fn deserialize(value: &mut Value<'de>) -> Result<Self, DeserError> {
        let val = value.take_string(Some("an SPDX licensee string"))?;

        match spdx::Licensee::parse(&val) {
            Ok(licensee) => Ok(Self(Spanned::with_span(licensee, value.span))),
            Err(pe) => {
                let offset = value.span.start;

                Err(toml_span::Error {
                    kind: toml_span::ErrorKind::Custom(pe.reason.to_string().into()),
                    span: (pe.span.start + offset..pe.span.end + offset).into(),
                    line_info: None,
                }
                .into())
            }
        }
    }
}

#[cfg(test)]
impl serde::Serialize for Licensee {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        self.0.value.to_string().serialize(serializer)
    }
}

#[cfg_attr(test, derive(serde::Serialize))]
pub(crate) struct Deprecated {
    /// Determines what happens when license information cannot be determined
    /// for a crate
    pub unlicensed: LintLevel,
    /// Accepts license requirements based on whether they are OSI Approved or
    /// FSF/Free Libre
    pub allow_osi_fsf_free: BlanketAgreement,
    /// Determines what happens when a copyleft license is detected
    pub copyleft: LintLevel,
    /// Determines what happens when a license doesn't match any previous
    /// predicates
    pub default: LintLevel,
    /// Licenses that will be rejected in a license expression
    pub deny: Vec<Licensee>,
}

/// Top level configuration for the a license check
pub struct Config {
    pub private: Private,
    /// The minimum confidence threshold we allow when determining the license
    /// in a text file, on a 0.0 (none) to 1.0 (maximum) scale
    pub confidence_threshold: f32,
    /// Licenses that will be allowed in a license expression
    pub allow: Vec<Licensee>,
    /// Determines the response to licenses in th `allow`ed list which do not
    /// exist in the dependency tree.
    pub unused_allowed_license: LintLevel,
    /// Overrides the license expression used for a particular crate as long as
    /// it exactly matches the specified license files and hashes
    pub clarify: Vec<Clarification>,
    /// Allow 1 or more additional licenses on a per-crate basis, so particular
    /// licenses aren't accepted for every possible crate and must be opted into
    pub exceptions: Vec<Exception>,
    /// If true, performs license checks for dev-dependencies for workspace
    /// crates as well
    pub include_dev: bool,
    deprecated: Option<Deprecated>,
    deprecated_spans: Vec<Span>,
}

impl Default for Config {
    fn default() -> Self {
        Self {
            private: Private::default(),
            unused_allowed_license: LintLevel::Warn,
            confidence_threshold: DEFAULT_CONFIDENCE_THRESHOLD,
            allow: Vec::new(),
            clarify: Vec::new(),
            exceptions: Vec::new(),
            include_dev: false,
            deprecated: None,
            deprecated_spans: Vec::new(),
        }
    }
}

impl<'de> Deserialize<'de> for Config {
    fn deserialize(value: &mut Value<'de>) -> Result<Self, DeserError> {
        let mut th = TableHelper::new(value)?;

        let version = th.optional("version").unwrap_or(1);

        let mut fdeps = Vec::new();

        let private = th.optional("private").unwrap_or_default();
        let unlicensed = deprecated(&mut th, "unlicensed", &mut fdeps).unwrap_or(LintLevel::Deny);
        let allow_osi_fsf_free =
            deprecated(&mut th, "allow-osi-fsf-free", &mut fdeps).unwrap_or_default();
        let copyleft = deprecated(&mut th, "copyleft", &mut fdeps).unwrap_or(LintLevel::Warn);
        let default = deprecated(&mut th, "default", &mut fdeps).unwrap_or(LintLevel::Deny);
        let confidence_threshold = th
            .optional("confidence-threshold")
            .unwrap_or(DEFAULT_CONFIDENCE_THRESHOLD);
        let deny = deprecated(&mut th, "deny", &mut fdeps).unwrap_or_default();
        let allow = th.optional("allow").unwrap_or_default();
        let unused_allowed_license = th
            .optional("unused-allowed-license")
            .unwrap_or(LintLevel::Warn);
        let clarify = th.optional("clarify").unwrap_or_default();
        let exceptions = th.optional("exceptions").unwrap_or_default();
        let include_dev = th.optional("include-dev").unwrap_or_default();

        th.finalize(None)?;

        let deprecated = if version <= 1 {
            Some(Deprecated {
                unlicensed,
                allow_osi_fsf_free,
                copyleft,
                default,
                deny,
            })
        } else {
            None
        };

        Ok(Self {
            private,
            confidence_threshold,
            allow,
            unused_allowed_license,
            clarify,
            exceptions,
            include_dev,
            deprecated,
            deprecated_spans: fdeps,
        })
    }
}

impl crate::cfg::UnvalidatedConfig for Config {
    type ValidCfg = ValidConfig;

    /// Validates the configuration provided by the user.
    ///
    /// 1. Ensures all SPDX identifiers are valid
    /// 1. Ensures all SPDX expressions are valid
    /// 1. Ensures the same license is not both allowed and denied
    fn validate(self, mut ctx: ValidationContext<'_>) -> Self::ValidCfg {
        use rayon::prelude::*;

        let mut ignore_sources = Vec::with_capacity(self.private.ignore_sources.len());
        for aurl in &self.private.ignore_sources {
            match url::Url::parse(aurl.as_ref()) {
                Ok(mut url) => {
                    crate::normalize_git_url(&mut url);
                    ignore_sources.push(url);
                }
                Err(pe) => {
                    ctx.push(
                        Diagnostic::error()
                            .with_message("failed to parse url")
                            .with_labels(vec![
                                Label::primary(ctx.cfg_id, aurl.span).with_message(pe.to_string())
                            ]),
                    );
                }
            }
        }

        let mut deprecated = self.deprecated;

        let mut denied = deprecated
            .as_mut()
            .map_or(Vec::new(), |d| std::mem::take(&mut d.deny));
        let mut allowed = self.allow;

        denied.par_sort();
        allowed.par_sort();

        let mut exceptions = Vec::with_capacity(self.exceptions.len());
        exceptions.extend(self.exceptions.into_iter().map(|exc| ValidException {
            spec: exc.spec,
            allowed: exc.allow,
            file_id: ctx.cfg_id,
        }));

        // Ensure the config doesn't contain the same exact license as both
        // denied and allowed, that's confusing and probably not intended, so
        // they should pick one
        for (di, d) in denied.iter().enumerate() {
            if let Ok(ai) = allowed.binary_search(d) {
                ctx.push(
                    Diagnostic::error()
                        .with_message("a license id was specified in both `allow` and `deny`")
                        .with_labels(vec![
                            Label::secondary(ctx.cfg_id, denied[di].0.span).with_message("deny"),
                            Label::secondary(ctx.cfg_id, allowed[ai].0.span).with_message("allow"),
                        ]),
                );
            }
        }

        let mut clarifications = Vec::with_capacity(self.clarify.len());
        for c in self.clarify {
            let expr = match spdx::Expression::parse(c.expression.as_ref()) {
                Ok(validated) => validated,
                Err(err) => {
                    let offset = c.expression.span.start;
                    let expr_span = offset + err.span.start..offset + err.span.end;

                    ctx.push(
                        Diagnostic::error()
                            .with_message("unable to parse license expression")
                            .with_labels(vec![Label::primary(ctx.cfg_id, expr_span)
                                .with_message(err.reason.to_string())]),
                    );

                    continue;
                }
            };

            let mut license_files = c.license_files;
            license_files.sort_by(|a, b| a.path.cmp(&b.path));

            clarifications.push(ValidClarification {
                spec: c.spec,
                expr_offset: c.expression.span.start,
                expression: expr,
                license_files,
            });
        }

        use crate::diag::general::{Deprecated, DeprecationReason};

        // Output any deprecations, we'll remove the fields at the same time we
        // remove all the logic they drive
        for dep in self.deprecated_spans {
            ctx.push(
                Deprecated {
                    reason: DeprecationReason::WillBeRemoved(Some(
                        "https://github.com/EmbarkStudios/cargo-deny/pull/611",
                    )),
                    key: dep,
                    file_id: ctx.cfg_id,
                }
                .into(),
            );
        }

        ValidConfig {
            file_id: ctx.cfg_id,
            private: self.private,
            unused_allowed_license: self.unused_allowed_license,
            confidence_threshold: self.confidence_threshold,
            clarifications,
            exceptions,
            denied,
            allowed,
            ignore_sources,
            deprecated,
            include_dev: self.include_dev,
        }
    }
}

pub fn load_exceptions(
    cfg: &mut ValidConfig,
    path: crate::PathBuf,
    files: &mut crate::diag::Files,
    diags: &mut Vec<Diagnostic>,
) {
    let content = match std::fs::read_to_string(&path) {
        Ok(c) => c,
        Err(err) => {
            diags.push(
                Diagnostic::error()
                    .with_message("failed to read exceptions override")
                    .with_notes(vec![format!("path = '{path}'"), format!("error = {err:#}")]),
            );
            return;
        }
    };

    let file_id = files.add(path, content);

    let get_exceptions = || -> Result<Vec<Exception>, DeserError> {
        let mut parsed = toml_span::parse(files.source(file_id))?;
        let mut th = TableHelper::new(&mut parsed)?;
        let exceptions = th.required("exceptions")?;
        th.finalize(None)?;
        Ok(exceptions)
    };

    match get_exceptions() {
        Ok(exceptions) => {
            cfg.exceptions.reserve(exceptions.len());
            for exc in exceptions {
                cfg.exceptions.push(ValidException {
                    spec: exc.spec,
                    allowed: exc.allow,
                    file_id,
                });
            }
        }
        Err(err) => {
            diags.extend(err.errors.into_iter().map(|err| err.to_diagnostic(file_id)));
        }
    }
}

#[doc(hidden)]
#[cfg_attr(test, derive(PartialEq))]
pub struct ValidClarification {
    pub spec: PackageSpec,
    pub expr_offset: usize,
    pub expression: spdx::Expression,
    pub license_files: Vec<FileSource>,
}

#[cfg(test)]
impl serde::Serialize for ValidClarification {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        use serde::ser::SerializeMap;
        let mut map = serializer.serialize_map(Some(4))?;
        map.serialize_entry("spec", &self.spec)?;
        map.serialize_entry("expression", self.expression.as_ref())?;
        map.serialize_entry("license-files", &self.license_files)?;
        map.end()
    }
}

#[doc(hidden)]
#[derive(Debug, PartialEq, Eq)]
#[cfg_attr(test, derive(serde::Serialize))]
pub struct ValidException {
    pub spec: PackageSpec,
    pub allowed: Vec<Licensee>,
    pub file_id: FileId,
}

#[doc(hidden)]
#[cfg_attr(test, derive(serde::Serialize))]
pub struct ValidConfig {
    pub file_id: FileId,
    pub private: Private,
    pub unused_allowed_license: LintLevel,
    pub confidence_threshold: f32,
    pub denied: Vec<Licensee>,
    pub allowed: Vec<Licensee>,
    pub clarifications: Vec<ValidClarification>,
    pub exceptions: Vec<ValidException>,
    pub ignore_sources: Vec<url::Url>,
    pub(crate) deprecated: Option<Deprecated>,
    pub include_dev: bool,
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::test_utils::{write_diagnostics, ConfigData};

    struct Licenses {
        licenses: Config,
    }

    impl<'de> toml_span::Deserialize<'de> for Licenses {
        fn deserialize(
            value: &mut toml_span::value::Value<'de>,
        ) -> Result<Self, toml_span::DeserError> {
            let mut th = toml_span::de_helpers::TableHelper::new(value)?;
            let licenses = th.required("licenses").unwrap();
            th.finalize(None)?;
            Ok(Self { licenses })
        }
    }

    #[test]
    fn deserializes_licenses_cfg() {
        let cd = ConfigData::<Licenses>::load("tests/cfg/licenses.toml");
        let validated = cd.validate_with_diags(
            |l| l.licenses,
            |files, diags| {
                let diags = write_diagnostics(files, diags.into_iter());
                insta::assert_snapshot!(diags);
            },
        );

        insta::assert_json_snapshot!(validated);
    }

    #[test]
    fn correct_duplicate_license_spans() {
        let cfg = r#"[licenses]
allow = [
    "MIT",
    "Apache-2.0",
    "BSD-3-Clause",
    "ISC",
    "CC0-1.0",
    "Unicode-DFS-2016",
]
deny = [
   "MIT",
    "GPL-1.0",
    "GPL-2.0",
    "GPL-3.0",
    "AGPL-3.0",
]"#;

        let cd = ConfigData::<Licenses>::load_str("license-in-allow-and-deny", cfg);
        let _validated = cd.validate_with_diags(
            |l| l.licenses,
            |files, diags| {
                let diags = write_diagnostics(files, diags.into_iter());
                insta::assert_snapshot!(diags);
            },
        );
    }
}
