// 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::{
    cell::{Ref, RefCell},
    ffi::OsStr,
    path::{Path, PathBuf},
};

use crate::{registry::Registry, target::Provider};
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,
    cache_dir: PathBuf,
    name: String,
    // Use a RefCell to provide interior mutability on the registry so that it can
    // be lazily loaded without taking a mutable reference on the Project.
    registry: RefCell<Option<Registry>>,
}

impl Project {
    const MANIFEST_FILE: &str = "qg.toml";
    const CACHE_DIRECTORY: &str = "qg-cache";

    /// 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();
        if !project_root.join(Self::MANIFEST_FILE).exists() {
            return Err(Error::ProjectNotFound);
        }

        let manifest = self::File::new(project_root.join(Self::MANIFEST_FILE))
            .deserialize_toml::<Manifest>()?;

        Ok(Self {
            root: project_root.to_owned(),
            cache_dir: project_root.join(Self::CACHE_DIRECTORY),
            name: manifest.project.name,
            registry: RefCell::new(None),
        })
    }

    /// 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 project = Self {
            root: root.to_owned(),
            cache_dir: root.join(Self::CACHE_DIRECTORY),
            name: name.into(),
            registry: RefCell::new(None),
        };

        let manifest = Manifest::new(name);
        project.root_manifest().serialize_toml(&manifest)?;

        Ok(project)
    }

    /// 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 [`File`](self::File) representing some file located at `path`
    /// within the project's cache directory.
    ///
    /// # Errors
    /// Returns an [`Error::InvalidPath`] if the provided path is absolute.
    pub fn cache_file(&self, path: impl AsRef<OsStr>) -> Result<self::File> {
        Self::relative_file(&self.cache_dir, Path::new(path.as_ref()))
    }

    /// Returns the target registry for this project.  Will locate and parse
    /// manifests if they have not already been read.
    ///
    /// # Errors
    /// Returns an error if manifest files could not be read or are improperly
    /// structured.
    pub fn registry(&self) -> Result<Ref<Registry>> {
        {
            // Scope the mutable borrow to just the existence check and
            // manifest parsing.
            let mut registry = self.registry.borrow_mut();
            if registry.is_none() {
                *registry = Some(self.parse_manifests()?);
            }
        }

        Ok(Ref::map(self.registry.borrow(), |registry| {
            registry
                .as_ref()
                .expect("registry should be valid due to being created above")
        }))
    }

    /// Reads `qg` manifest files starting from the project root into a registry
    /// of available packages.
    ///
    /// # Errors
    /// Returns an error if manifest files could not be read or are improperly
    /// structured.
    fn parse_manifests(&self) -> Result<Registry> {
        let root_manifest_file = self.root_manifest();
        let root_manifest = root_manifest_file.deserialize_toml::<Manifest>()?;
        let mut registry = Registry::new();

        let project_provider = Provider::new(
            &root_manifest.project.name,
            root_manifest_file.path(),
            false,
        );
        registry.add_provider(project_provider)?;

        for (name, target) in root_manifest.targets {
            registry.add_target(crate::Target::from_manifest(
                &name,
                &root_manifest.project.name,
                target.namespace.is_global(),
                target,
            )?)?;
        }

        for (provider, desc) in &root_manifest.providers {
            if let Some(manifest) = &desc.manifest {
                let provider_file = root_manifest_file.relative_file(manifest);

                let provider_data = provider_file.deserialize_toml::<manifest::ProviderFile>()?;
                let global_provider = if let Some(desc) = &provider_data.provider {
                    desc.namespace.is_global()
                } else {
                    false
                };

                registry.add_provider(Provider::new(
                    provider,
                    provider_file.path(),
                    global_provider,
                ))?;

                for (name, target) in provider_data.targets {
                    registry.add_target(crate::Target::from_manifest(
                        &name,
                        provider,
                        global_provider || target.namespace.is_global(),
                        target,
                    )?)?;
                }
            }
        }

        Ok(registry)
    }

    fn root_manifest(&self) -> self::File {
        self.file(Self::MANIFEST_FILE)
            .expect("manifest path is not absolute")
    }

    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 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 {
            cache_dir: root.join("qg-cache"),
            root,
            name: "qg2".into(),
            registry: RefCell::new(None),
        };

        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")
        );
        assert_eq!(
            project.cache_file("downloads.xml").unwrap().path(),
            Path::new("/qg/qg-cache/downloads.xml")
        );
    }

    #[test]
    fn file_invalid_path() {
        let root = PathBuf::from("/qg");
        let project = Project {
            cache_dir: root.join("qg-cache"),
            root,
            name: "qg2".into(),
            registry: RefCell::new(None),
        };

        assert!(matches!(
            project.file("/bin").unwrap_err(),
            Error::InvalidPath,
        ));
        assert!(matches!(
            project.cache_file("/").unwrap_err(),
            Error::InvalidPath,
        ));
        assert!(matches!(project.file("").unwrap_err(), Error::InvalidPath));
        assert!(matches!(
            project.cache_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());
    }
}
