// Copyright 2022 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::{errors::ParseError, parse::PackageName, UrlParts};

/// A relative URL locating a Fuchsia package. Used with a subpackage context.
/// Has the form "<name>" where:
///   * "name" is a valid package name
/// https://fuchsia.dev/fuchsia-src/concepts/packages/package_url
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RelativePackageUrl {
    path: PackageName,
}

impl RelativePackageUrl {
    pub(crate) fn from_parts(parts: UrlParts) -> Result<Self, ParseError> {
        let UrlParts { scheme, host, path, hash, resource } = parts;
        if scheme.is_some() {
            return Err(ParseError::CannotContainScheme);
        }
        if host.is_some() {
            return Err(ParseError::HostMustBeEmpty);
        }
        if hash.is_some() {
            return Err(ParseError::CannotContainHash);
        }
        if resource.is_some() {
            return Err(ParseError::CannotContainResource);
        }
        let (name, variant) = crate::parse_path_to_name_and_variant(&path)?;
        if variant.is_some() {
            return Err(ParseError::RelativePathCannotSpecifyVariant);
        }
        Ok(Self { path: name })
    }

    /// Parse a relative package URL.
    pub fn parse(url: &str) -> Result<Self, ParseError> {
        let parts = UrlParts::parse(url)?;
        let relative_package_url = Self::from_parts(parts)?;
        let () = crate::validate_inverse_relative_url(url)?;
        Ok(relative_package_url)
    }
}

impl std::str::FromStr for RelativePackageUrl {
    type Err = ParseError;

    fn from_str(url: &str) -> Result<Self, Self::Err> {
        Self::parse(url)
    }
}

impl From<PackageName> for RelativePackageUrl {
    fn from(path: PackageName) -> Self {
        Self { path }
    }
}

impl From<RelativePackageUrl> for PackageName {
    fn from(url: RelativePackageUrl) -> Self {
        url.path
    }
}

impl std::convert::TryFrom<&str> for RelativePackageUrl {
    type Error = ParseError;

    fn try_from(value: &str) -> Result<Self, Self::Error> {
        Self::parse(value)
    }
}

impl std::fmt::Display for RelativePackageUrl {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        self.path.fmt(f)
    }
}

impl AsRef<str> for RelativePackageUrl {
    fn as_ref(&self) -> &str {
        self.path.as_ref()
    }
}

impl From<&RelativePackageUrl> for String {
    fn from(url: &RelativePackageUrl) -> Self {
        url.to_string()
    }
}

impl serde::Serialize for RelativePackageUrl {
    fn serialize<S: serde::Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
        self.to_string().serialize(ser)
    }
}

impl<'de> serde::Deserialize<'de> for RelativePackageUrl {
    fn deserialize<D>(de: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let url = String::deserialize(de)?;
        Ok(Self::parse(&url).map_err(|err| serde::de::Error::custom(err))?)
    }
}

#[cfg(test)]
mod tests {
    use {super::*, assert_matches::assert_matches, std::convert::TryFrom as _};

    #[test]
    fn parse_err() {
        for (url, err) in [
            ("fuchsia-boot://example.org/name", ParseError::CannotContainScheme),
            ("fuchsia-pkg://", ParseError::CannotContainScheme),
            ("fuchsia-pkg://name", ParseError::CannotContainScheme),
            ("fuchsia-pkg:///name", ParseError::CannotContainScheme),
            ("//example.org/name", ParseError::HostMustBeEmpty),
            (
                "///name",
                ParseError::InvalidRelativePath("///name".to_string(), Some("name".to_string())),
            ),
            ("example.org/name", ParseError::RelativePathCannotSpecifyVariant),
            ("fuchsia-pkg://example.org/name", ParseError::CannotContainScheme),
            ("name/variant", ParseError::RelativePathCannotSpecifyVariant),
            ("name#resource", ParseError::CannotContainResource),
            (
                "/name",
                ParseError::InvalidRelativePath("/name".to_string(), Some("name".to_string())),
            ),
            (".", ParseError::MissingName),
            ("..", ParseError::MissingName),
            (
                "name?hash=0000000000000000000000000000000000000000000000000000000000000000",
                ParseError::CannotContainHash,
            ),
        ] {
            assert_matches!(
                RelativePackageUrl::parse(url),
                Err(e) if e == err,
                "the url {:?}, expected: {:?}", url, err
            );
            assert_matches!(
                url.parse::<RelativePackageUrl>(),
                Err(e) if e == err,
                "the url {:?}, expected: {:?}", url, err
            );
            assert_matches!(
                RelativePackageUrl::try_from(url),
                Err(e) if e == err,
                "the url {:?}, expected: {:?}", url, err
            );
            assert_matches!(
                serde_json::from_str::<RelativePackageUrl>(url),
                Err(_),
                "the url {:?}",
                url
            );
        }
    }

    #[test]
    fn parse_ok() {
        for url in ["name", "other3-name"] {
            let normalized_url = url.trim_start_matches('/');
            let json_url = format!("\"{url}\"");
            let normalized_json_url = format!("\"{normalized_url}\"");

            // Creation
            let name = normalized_url.parse::<crate::PackageName>().unwrap();
            let validate = |parsed: &RelativePackageUrl| {
                assert_eq!(parsed.path, name);
            };
            validate(&RelativePackageUrl::parse(url).unwrap());
            validate(&url.parse::<RelativePackageUrl>().unwrap());
            validate(&RelativePackageUrl::try_from(url).unwrap());
            validate(&serde_json::from_str::<RelativePackageUrl>(&json_url).unwrap());

            // Stringification
            assert_eq!(
                RelativePackageUrl::parse(url).unwrap().to_string(),
                normalized_url,
                "the url {:?}",
                url
            );
            assert_eq!(
                RelativePackageUrl::parse(url).unwrap().as_ref(),
                normalized_url,
                "the url {:?}",
                url
            );
            assert_eq!(
                serde_json::to_string(&RelativePackageUrl::parse(url).unwrap()).unwrap(),
                normalized_json_url,
                "the url {:?}",
                url
            );
        }
    }
}
