// 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::{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()),
        )
    }

    /// 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:?})."
            );
        }
    }
}
