// 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();

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

        let _ = 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:?})."
            );
        }
    }
}
