// 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::path::{Path, PathBuf};

use crate::project::manifest;

/// 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,
        }
    }
}

/// An 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)]
enum Metadata {
    DepOnly,

    // TODO(frolv): These shouldn't store the manifest data directly but convert
    // it into a more usable in-memory format.
    Cipd(manifest::CipdPackage),
    Download(manifest::DownloadablePackage),
}

impl From<manifest::TargetType> for Metadata {
    fn from(tt: manifest::TargetType) -> Self {
        match tt {
            manifest::TargetType::Cipd(data) => Self::Cipd(data),
            manifest::TargetType::Download(data) => Self::Download(data),
        }
    }
}

impl Target {
    pub(crate) fn from_manifest(
        name: &str,
        provider: &str,
        global: bool,
        target: manifest::Target,
    ) -> Self {
        Self {
            name: name.to_owned(),
            provider: provider.to_owned(),
            global,
            dependencies: target.deps,
            metadata: target.desc.map_or(Metadata::DepOnly, Metadata::from),
        }
    }

    /// 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 Iterator<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",
        }
    }
}
