// 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::{
    ffi::OsStr,
    fs,
    path::{Path, PathBuf},
    sync::Arc,
};

use crate::{executor::Executor, registry::Registry, Target};
use crate::{Error, Result};
use manifest::Manifest;

pub mod file;
pub(crate) mod manifest;

#[doc(inline)]
pub use file::File;

/// A `qg`-based project.
#[derive(Debug)]
pub struct Project {
    root: PathBuf,
    qg_dir: PathBuf,
    name: String,
    registry: Arc<Registry>,
}

impl Project {
    const MANIFEST_FILE: &str = "qg.toml";
    const QG_DIRECTORY: &str = "qg";

    /// Checks if a project name is valid.
    ///
    /// Names may consist of unicode letters or numbers, hyphens, and underscores.
    #[must_use]
    pub fn name_is_valid(name: &str) -> bool {
        !name.is_empty()
            && name
                .chars()
                .all(|c| c.is_alphanumeric() || c == '-' || c == '_')
    }

    /// Searches for a qg project in the current directory and its ancestors.
    ///
    /// # Errors
    /// May return one of the following errors:
    /// - [`Error::File`]: Failed to access the filesystem.
    /// - [`Error::ProjectNotFound`]: No project could be located.
    pub fn locate() -> Result<Self> {
        let cwd = std::env::current_dir()?;
        let cwd = cwd.as_path();
        Self::locate_from_path(cwd)
    }

    // Implementation details of `locate()` without looking up the
    // current working directory.  This allows testing of the core
    // logic without dependence on the environment and makes it
    // friendlier to parallel test execution.
    fn locate_from_path<P: AsRef<Path>>(cwd: P) -> Result<Self> {
        let mut cwd = cwd.as_ref();

        loop {
            if let Ok(project) = Self::load(cwd) {
                return Ok(project);
            }

            cwd = match cwd.parent() {
                Some(p) => p,
                None => return Err(Error::ProjectNotFound),
            }
        }
    }

    /// Load a qg project from an specific path.
    ///
    /// # Errors
    /// May return one of the following errors:
    /// - [`Error::File`]: Failed to access the filesystem.
    /// - [`Error::ProjectNotFound`]: No project manifest found in `project_root`.
    pub fn load<P: AsRef<Path>>(project_root: P) -> Result<Self> {
        let project_root = project_root.as_ref();
        let manifest_path = project_root.join(Self::MANIFEST_FILE);
        if !manifest_path.exists() {
            return Err(Error::ProjectNotFound);
        }

        let manifest_file = self::File::new(manifest_path);
        let manifest = manifest_file.deserialize_toml::<Manifest>()?;

        let registry = Registry::parse_manifests(&manifest_file)?;

        Ok(Self {
            root: project_root.to_owned(),
            qg_dir: project_root.join(Self::QG_DIRECTORY),
            name: manifest.project.name,
            registry: Arc::new(registry),
        })
    }

    /// Initializes a new project at the specified `root`.
    ///
    /// # Errors
    /// Returns an error if the root directory does not exist or is
    /// inaccessible.
    ///
    /// # Panics
    /// Temporarily panics if a project already exists within `root` as
    /// subprojects are not yet supported.
    pub fn create(root: &Path, name: &str) -> Result<Self> {
        let parent_project = match Self::locate() {
            Ok(p) => Some(p),
            Err(Error::ProjectNotFound) => None,
            Err(e) => return Err(e),
        };

        // TODO(frolv): Initialize a new subproject in an existing project.
        assert!(parent_project.is_none(), "subprojects not yet supported");

        if !Self::name_is_valid(name) {
            return Err(Error::InvalidName(name.into()));
        }

        let manifest = Manifest::new(name);
        Self::relative_file(root, Path::new(Self::MANIFEST_FILE))?.serialize_toml(&manifest)?;

        Self::load(root)
    }

    /// Returns the root directory of the project.
    #[must_use]
    pub fn root(&self) -> &Path {
        &self.root
    }

    /// Returns the name of the project.
    #[must_use]
    pub fn name(&self) -> &str {
        &self.name
    }

    /// Returns a [`File`](self::File) representing some configuration file located
    /// at `path` within the project directory.
    ///
    /// # Errors
    /// Returns an [`Error::InvalidPath`] if the provided path is absolute.
    pub fn file(&self, path: impl AsRef<OsStr>) -> Result<self::File> {
        Self::relative_file(&self.root, Path::new(path.as_ref()))
    }

    /// Returns a `PathBuf` pointing to the directory located at `path` within
    /// the project root.  Will create the directory if it does not exist.
    ///
    /// # Errors
    /// Returns an error if the directory does not exist and can not be
    /// created.
    fn directory(&self, path: impl AsRef<Path>) -> Result<PathBuf> {
        let dir_path = self.root.join(path.as_ref());
        fs::create_dir_all(&dir_path)?;
        Ok(dir_path)
    }

    /// Returns a `PathBuf` pointing to the output directory for a given target.
    /// Will create the directory if it does not exist.
    ///
    /// # Errors
    /// Returns an error if the directory does not exist and can not be
    /// created.
    pub fn target_output_directory(&self, target: &Target) -> Result<PathBuf> {
        self.directory(
            self.qg_dir
                .join("out")
                .join(target.provider())
                .join(target.name()),
        )
    }

    /// Returns a `PathBuf` pointing to the output directory for a given target.
    /// Will create the directory if it does not exist.
    ///
    /// # Errors
    /// Returns an error if the directory does not exist and can not be
    /// created.
    pub fn target_work_directory(&self, target: &Target) -> Result<PathBuf> {
        self.directory(
            self.qg_dir
                .join("work")
                .join(target.provider())
                .join(target.name()),
        )
    }

    /// Executes a single target in the build graph.
    ///
    /// # Errors
    /// Returns an error if the target or any of its dependencies failed to run.
    pub async fn run_target(&self, target: &str) -> Result<()> {
        // TODO(frolv): Configure the number of workers based on the system thread count.
        let mut executor = Executor::new(self, 2);
        executor.execute_target(target).await
    }

    /// Returns the target registry for this project.
    #[must_use]
    pub fn registry(&self) -> Arc<Registry> {
        self.registry.clone()
    }

    fn relative_file(root: &Path, path: &Path) -> Result<self::File> {
        if !path.as_os_str().is_empty() && !path.is_absolute() {
            Ok(self::File::new(root.join(path)))
        } else {
            Err(Error::InvalidPath)
        }
    }
}

#[cfg(test)]
mod tests {
    use std::collections::HashSet;

    use crate::{target::Metadata, test_util::TestProject};

    use super::*;

    #[test]
    fn name_is_valid_valid() {
        assert!(Project::name_is_valid("qg"));
        assert!(Project::name_is_valid("my-project"));
        assert!(Project::name_is_valid("my_other_project"));
        assert!(Project::name_is_valid("мой-проект"));
    }

    #[test]
    fn name_is_valid_invalid() {
        assert!(!Project::name_is_valid(""));
        assert!(!Project::name_is_valid("project!"));
        assert!(!Project::name_is_valid("💩"));
    }

    #[test]
    fn file_valid_path() {
        let root = PathBuf::from("/qg");
        let project = Project {
            qg_dir: root.join("qg"),
            root,
            name: "qg2".into(),
            registry: Arc::new(Registry::new()),
        };

        assert_eq!(
            project.file("emoji.json").unwrap().path(),
            Path::new("/qg/emoji.json")
        );
        assert_eq!(
            project.file("secrets/nuclear_codes.toml").unwrap().path(),
            Path::new("/qg/secrets/nuclear_codes.toml")
        );
    }

    #[test]
    fn file_invalid_path() {
        let root = PathBuf::from("/qg");
        let project = Project {
            qg_dir: root.join("qg"),
            root,
            name: "qg2".into(),
            registry: Arc::new(Registry::new()),
        };

        assert!(matches!(
            project.file("/bin").unwrap_err(),
            Error::InvalidPath,
        ));
        assert!(matches!(project.file("").unwrap_err(), Error::InvalidPath));
    }

    #[test]
    fn locate_test_project() {
        // Test that `locate()` and find a manifest from a parent directory.
        let project =
            Project::locate_from_path("./src/test_projects/simple/subdir/subsubdir").unwrap();
        assert_eq!(project.name, "test-qg-project");
    }

    #[test]
    fn load_test_project() {
        // Loads from the project root succeed.
        let project = Project::load("./src/test_projects/simple").unwrap();
        assert_eq!(project.name, "test-qg-project");

        // Loads from a project subdirectory fail.
        assert!(Project::load("./src/test_projects/simple/subdir/subsubdir").is_err());
    }

    #[test]
    fn out_and_work_directories() {
        let test_project = TestProject::new("./src/test_projects/dependency_test").unwrap();
        let project = &test_project.project;
        assert_eq!(project.name, "dep-test");

        // Neither dep-test:a's out or work directories should exist before we
        // ask for their paths.
        assert!(!test_project.relative_path("qg/out/dep-test/a").exists());
        assert!(!test_project.relative_path("qg/work/dep-test/a").exists());

        let target = project.registry().get_target("dep-test:a").unwrap();

        project.target_output_directory(&target).unwrap();
        assert!(test_project.relative_path("qg/out/dep-test/a").exists());

        project.target_work_directory(&target).unwrap();
        assert!(test_project.relative_path("qg/work/dep-test/a").exists());
    }

    #[test]
    fn simple_dependencies() {
        let test_project = TestProject::new("./src/test_projects/dependency_test").unwrap();
        let project = &test_project.project;
        assert_eq!(project.name, "dep-test");

        let registry = project.registry();
        let a_id = registry.get_node_id("dep-test:a").unwrap();
        let b_id = registry.get_node_id("dep-test:b").unwrap();
        let c_id = registry.get_node_id("dep-test:c").unwrap();
        let d_id = registry.get_node_id("dep-test:d").unwrap();
        let e_id = registry.get_node_id("dep-test:e").unwrap();

        for (name, id, duration_ticks, children) in [
            ("a", a_id, 1, vec![b_id, c_id]),
            ("b", b_id, 2, vec![]),
            ("c", c_id, 3, vec![d_id, e_id]),
            ("d", d_id, 4, vec![]),
            ("e", e_id, 5, vec![]),
        ] {
            let target = registry.get_target_by_id(id).unwrap();
            let Metadata::Fake(fake) = target.metadata() else {
                panic!("{name} is not of the target type Fake: {target:?}.");
            };

            assert_eq!(
                fake.duration_ticks,
                duration_ticks,
                "Node {name}'s durations ticks ({}) do not match expected value ({duration_ticks}).",
                fake.duration_ticks);

            let deps: HashSet<_> = registry.node_deps(id).collect();
            let expected: HashSet<_> = children.into_iter().collect();

            assert_eq!(
                deps, expected,
                "Node {name}'s dependencies ({deps:?}) do not match expected value ({expected:?})."
            );
        }
    }
}
