// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

mod template_helpers;
mod util;

use anyhow::{anyhow, bail};
use chrono::{Datelike, Utc};
use handlebars::Handlebars;
use serde::Serialize;
use std::collections::HashMap;
use std::path::{Component, Path, PathBuf};
use std::str::FromStr;
use std::{env, fmt, fs, io};
use structopt::StructOpt;
use tempfile::tempdir;
use termion::{color, style};

const LANG_AGNOSTIC_EXTENSION: &'static str = "tmpl";

fn main() -> Result<(), anyhow::Error> {
    let args = CreateArgs::from_args();
    if args.project_name.contains("_") {
        bail!("project-name cannot contain underscores");
    }
    let templates_dir_path = util::get_templates_dir_path()?;

    // Get the list of template file paths available to this project type and language.
    let template_files = find_template_files(
        &templates_dir_path.join("templates.json"),
        &args.project_type,
        &args.lang,
        &StdFs,
    )?;

    // Collect the template files for this project type and language.
    let template_tree = TemplateTree::from_file_list(
        &templates_dir_path,
        &template_files,
        &args.project_type,
        &StdFs,
    )?;

    // Register the template engine.
    let mut handlebars = Handlebars::new();
    handlebars.set_strict_mode(true);
    template_helpers::register_helpers(&mut handlebars);

    // Register partial templates.
    register_partial_templates(&mut handlebars, &templates_dir_path, &template_files, &StdFs)?;

    // Create the set of variables accessible to template files.
    let template_args = TemplateArgs::from_create_args(&args)?;

    // Execute the templates and render them to an in-memory representation.
    let project = template_tree.render(&mut handlebars, &template_args)?;

    // Write the rendered files to a temp directory.
    let dir = tempdir()?;
    let tmp_out_path = dir.path().join(&args.project_name);
    project.write(&tmp_out_path)?;

    // Rename the temp directory project to the final location.
    let dest_project_path = args.absolute_project_path()?;
    fs::rename(&tmp_out_path, &dest_project_path)
        .map_err(|e| anyhow!("rename to destination {:?} failed: {:?}", &dest_project_path, e))?;

    if !args.silent {
        println!("Project created at {}.", dest_project_path.to_string_lossy());

        // Find the parent BUILD.gn file and suggest adding the test target.
        let parent_build =
            dest_project_path.parent().map(|p| p.join("BUILD.gn")).filter(|b| b.exists());
        if let Some(parent_build) = parent_build {
            println!(
                "{}note:{} Don't forget to include the {}{}:tests{} GN target in the parent {}tests{} target ({}).",
                color::Fg(color::Yellow), color::Fg(color::Reset),
                style::Bold, &args.project_name, style::Reset,
                style::Bold, style::Reset,
                parent_build.to_string_lossy()
            );
        }
    }

    Ok(())
}

#[derive(Debug, StructOpt)]
#[structopt(name = "fx-create", about = "Creates scaffolding for new projects.", version = "0.1")]
#[structopt(rename_all = "kebab")]
struct CreateArgs {
    /// The type of project to create.
    ///
    /// This can be one of:
    ///
    /// - component-v1: A V1 component launched with appmgr,
    /// - component-v2: A V2 component launched with Component Manager,
    project_type: String,

    /// The name of the new project.
    ///
    /// This will be the name of the GN target and directory for the project.
    /// The name should not contain any underscores.
    project_name: String,

    /// The programming language.
    #[structopt(short, long)]
    lang: Language,

    /// Destination directory of new project (default current working directory).
    #[structopt(long)]
    dest: Option<PathBuf>,

    /// Override for the project include path. For testing.
    #[structopt(long)]
    override_project_path: Option<PathBuf>,

    /// Override the copyright year. For testing.
    #[structopt(long)]
    override_copyright_year: Option<u32>,

    /// When set, does not emit anything to stdout.
    #[structopt(long)]
    silent: bool,
}

impl CreateArgs {
    /// Returns the absolute path to the new project.
    fn absolute_project_path(&self) -> io::Result<PathBuf> {
        let parent_dir = if let Some(dest) = self.dest.as_ref() {
            if dest.is_absolute() {
                dest.clone()
            } else {
                env::current_dir()?.join(dest)
            }
        } else {
            env::current_dir()?
        };
        Ok(parent_dir.join(&self.project_name))
    }
}

/// Supported languages for project creation.
#[derive(Debug)]
enum Language {
    Rust,
    Cpp,
}

impl Language {
    /// Returns the language's template extension. Template
    /// files that match this extension belong to this language.
    fn template_extension(&self) -> &'static str {
        match self {
            Self::Rust => "tmpl-rust",
            Self::Cpp => "tmpl-cpp",
        }
    }

    // Check if the file's extension matches the language-specific template
    // extension or the general template extension.
    fn matches(&self, path: &Path) -> bool {
        if let Some(ext) = path.extension() {
            ext == self.template_extension() || ext == LANG_AGNOSTIC_EXTENSION
        } else {
            false
        }
    }
}

impl FromStr for Language {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(match s {
            "rust" => Self::Rust,
            "cpp" => Self::Cpp,
            _ => return Err(format!("unrecognized language \"{}\"", s)),
        })
    }
}

impl fmt::Display for Language {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(match self {
            Self::Rust => "rust",
            Self::Cpp => "cpp",
        })
    }
}

/// Given a path to a JSON file, extract a list of template files that match the
/// `project_type` and `lang`.
///
/// The JSON file must consist of a root list of strings, where each string is a path relative
/// to the directory that contains the JSON file.
///
/// E.g.
///
/// `out/default/host-tools/create_templates/templates.json`:
/// ```json
/// [
///     "component-v2/BUILD.gn.tmpl-rust",
///     "component-v2/src/main.rs.tmpl-rust"
/// ]
/// ```
///
/// This file is generated by the GN build rule in //tools/create/templates/BUILD.gn.
fn find_template_files<FR>(
    json_file: &Path,
    project_type: &str,
    lang: &Language,
    file_reader: &FR,
) -> Result<Vec<PathBuf>, anyhow::Error>
where
    FR: FileReader,
{
    let json_contents = file_reader.read_to_string(json_file)?;
    let template_files: Vec<PathBuf> = serde_json::from_slice(json_contents.as_bytes())?;
    let mut template_files: Vec<PathBuf> = template_files
        .into_iter()
        .filter(|p| {
            lang.matches(p)
                && (p.starts_with(project_type) || (is_partial_template(p) && is_root_file(p)))
        })
        .collect();
    template_files.sort();
    Ok(template_files)
}

/// Returns true if this path is a single segment path, e.g. "foo.txt".
fn is_root_file(path: &Path) -> bool {
    let mut iter = path.components();
    match iter.next() {
        Some(Component::Normal(_)) => iter.next().is_none(),
        _ => false,
    }
}

/// Returns true if the template file name begins with an `_`.
fn is_partial_template(path: impl AsRef<Path>) -> bool {
    path.as_ref()
        .file_name()
        .and_then(std::ffi::OsStr::to_str)
        .map(|f| f.starts_with('_'))
        .unwrap_or(false)
}

/// Registers any partial templates (templates whose file names begin with `_`) with the templating
/// engine.
fn register_partial_templates<FR>(
    handlebars: &mut Handlebars,
    templates_dir: &Path,
    template_files: &Vec<PathBuf>,
    file_reader: &FR,
) -> Result<(), anyhow::Error>
where
    FR: FileReader,
{
    for partial in template_files.into_iter().filter(|p| is_partial_template(p)) {
        let content = file_reader.read_to_string(templates_dir.join(partial))?;
        let partial = partial.with_extension("");

        // Unwrap is safe as the `is_partial_template` predicate expects a valid filename.
        let filename = util::filename_to_string(partial.file_name().unwrap())?;

        // `is_partial_template` guarantees this filename starts with a `_`.
        let partial_name = partial.with_file_name(&filename[1..]);

        handlebars.register_partial(&partial_name.display().to_string(), content)?;
    }
    Ok(())
}

/// The arguments passed in during template execution.
/// The fields defined here represent what variables can be present in template files.
/// Add a field here and populate it to make it accessible in a template.
///
/// NOTE: The fields are serialized to JSON when passed to templates. The serialization
/// process renames all fields to UPPERCASE.
#[derive(Debug, Serialize)]
#[serde(rename_all = "UPPERCASE")]
struct TemplateArgs {
    /// The current year, for use in copyright headers.
    /// Reference from a template with `{{COPYRIGHT_YEAR}}`.
    copyright_year: String,

    /// The project name, as given on the command line.
    /// Reference from a template with `{{PROJECT_NAME}}`.
    project_name: String,

    /// The path to the new project, relative to the FUCHSIA_DIR environment variable.
    /// Reference from a template with `{{PROJECT_PATH}}`.
    project_path: String,

    /// The project-type, as specified on the command line. E.g. 'component-v2'.
    project_type: String,
}

impl TemplateArgs {
    /// Build TemplateArgs from the program args and environment.
    fn from_create_args(create_args: &CreateArgs) -> Result<Self, anyhow::Error> {
        let project_path = if let Some(override_project_path) = &create_args.override_project_path {
            override_project_path.join(&create_args.project_name)
        } else {
            let absolute_project_path = create_args.absolute_project_path()?;
            let fuchsia_root = util::get_fuchsia_root()?;
            absolute_project_path
                .strip_prefix(&fuchsia_root)
                .map_err(|_| {
                    anyhow!(
                        "current working directory must be a descendant of FUCHSIA_DIR ({:?})",
                        &fuchsia_root
                    )
                })?
                .to_path_buf()
        };

        let copyright_year = if let Some(year) = &create_args.override_copyright_year {
            year.to_string()
        } else {
            Utc::now().year().to_string()
        };

        Ok(TemplateArgs {
            copyright_year,
            project_name: create_args.project_name.clone(),
            project_path: project_path
                .to_str()
                .ok_or_else(|| anyhow!("invalid path {:?}", &project_path))?
                .to_string(),
            project_type: create_args.project_type.clone(),
        })
    }
}

/// The in-memory filtered template file tree.
#[derive(Debug, PartialEq)]
enum TemplateTree {
    /// A file and its template contents.
    File { source: PathBuf, content: String },

    /// A directory and its entries.
    Dir(HashMap<String, Box<TemplateTree>>),
}

impl TemplateTree {
    /// Populate a TemplateTree from a set of template files, ignoring partial templates (template files
    /// whose names begin with `_`).
    fn from_file_list<FR>(
        template_dir: &Path,
        template_files: &Vec<PathBuf>,
        project_type: &str,
        file_reader: &FR,
    ) -> Result<Self, anyhow::Error>
    where
        FR: FileReader,
    {
        let template_files = template_files
            .into_iter()
            .filter(|p| !is_partial_template(p))
            .collect::<Vec<&PathBuf>>();
        if template_files.is_empty() {
            bail!("no templates found for project type \"{}\"", project_type);
        }
        let mut tree = TemplateTree::Dir(HashMap::new());
        for path in template_files {
            let content = file_reader.read_to_string(template_dir.join(path))?;

            // The original template source for error reporting.
            let source = Path::new("//tools/create/templates").join(path);

            // Strip the project prefix from the path, which we know is there.
            let path = path.strip_prefix(project_type).unwrap();

            // Strip the .tmpl* extension. This will uncover the intended extension.
            // Eg: foo.rs.tmpl-rust -> foo.rs
            let path = path.with_extension("");

            tree.insert(&path, source, content)?;
        }
        Ok(tree)
    }

    fn insert(
        &mut self,
        path: &Path,
        source: PathBuf,
        content: String,
    ) -> Result<(), anyhow::Error> {
        let subtree = match self {
            Self::Dir(ref mut subtree) => subtree,
            Self::File { .. } => bail!("cannot insert subtree into file"),
        };

        let mut path_iter = path.components();
        if let Some(Component::Normal(component)) = path_iter.next() {
            let name = util::filename_to_string(component)?;
            let rest = path_iter.as_path();
            if path_iter.next().is_some() {
                subtree
                    .entry(name)
                    .or_insert_with(|| Box::new(TemplateTree::Dir(HashMap::new())))
                    .insert(rest, source, content)?;
            } else {
                if subtree.insert(name, Box::new(TemplateTree::File { source, content })).is_some()
                {
                    bail!("duplicate paths");
                }
            }
            Ok(())
        } else {
            bail!("path must be relative and have no '..' or '.' components");
        }
    }

    /// Recursively renders this TemplateTree into a mirror type [`RenderedTree`],
    /// using `handlebars` as the template engine and `args` as the exported variables
    // accessible to the templates.
    fn render(
        &self,
        handlebars: &mut Handlebars,
        args: &TemplateArgs,
    ) -> Result<RenderedTree, handlebars::TemplateRenderError> {
        Ok(match self {
            Self::File { source, content } => {
                let template_name = source.display().to_string();
                handlebars.register_template_string(&template_name, &content)?;
                let args = TemplateArgsWithTemplatePath { args, template_path: &template_name };
                let result = RenderedTree::File(handlebars.render(&template_name, &args)?);
                handlebars.unregister_template(&template_name);
                result
            }
            Self::Dir(nested_templates) => {
                let mut rendered_subtree = HashMap::new();
                for (filename, template) in nested_templates {
                    rendered_subtree.insert(
                        handlebars.render_template(&filename, args)?,
                        Box::new(template.render(handlebars, args)?),
                    );
                }
                RenderedTree::Dir(rendered_subtree)
            }
        })
    }
}

#[derive(Serialize)]
#[serde(rename_all = "UPPERCASE")]
struct TemplateArgsWithTemplatePath<'a> {
    #[serde(flatten)]
    args: &'a TemplateArgs,
    template_path: &'a str,
}

/// An in-memory representation of a file tree, where the paths and contents have
/// all been executed and rendered into their final form.
/// This is the mirror of [`TemplateTree`].
#[derive(Debug, PartialEq)]
enum RenderedTree {
    /// A file and its contents.
    File(String),

    /// A directory and its entries.
    Dir(HashMap<String, Box<RenderedTree>>),
}

impl RenderedTree {
    /// Write the RenderedTree to the `dest` path.
    fn write(&self, dest: &Path) -> io::Result<()> {
        match self {
            Self::File(contents) => {
                fs::write(dest, &contents)?;
            }
            Self::Dir(tree) => {
                fs::create_dir(dest)?;
                for (filename, subtree) in tree {
                    let dest = dest.join(filename);
                    subtree.write(&dest)?;
                }
            }
        }
        Ok(())
    }
}

/// Trait to enable testing of the template tree creation logic.
/// Allows mocking out reading from the file system.
trait FileReader {
    fn read_to_string(&self, p: impl AsRef<Path>) -> io::Result<String>;
}

/// Standard library filesystem implementation of FileReader.
struct StdFs;

impl FileReader for StdFs {
    fn read_to_string(&self, p: impl AsRef<Path>) -> io::Result<String> {
        fs::read_to_string(p)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use matches::assert_matches;

    #[test]
    fn language_display_can_be_parsed() {
        assert_matches!(Language::Rust.to_string().parse(), Ok(Language::Rust));
        assert_matches!(Language::Cpp.to_string().parse(), Ok(Language::Cpp));
    }

    #[test]
    fn render_templates() {
        let templates = TemplateTree::Dir({
            let mut entries = HashMap::new();
            entries.insert(
                "file.h".to_string(),
                Box::new(TemplateTree::File {
                    source: PathBuf::from("//file.h.tmpl-cpp"),
                    content: "class {{PROJECT_NAME}};".to_string(),
                }),
            );
            entries.insert(
                "{{PROJECT_NAME}}_nested".to_string(),
                Box::new(TemplateTree::Dir({
                    let mut entries = HashMap::new();
                    entries.insert(
                        "file.h".to_string(),
                        Box::new(TemplateTree::File{
                            source: PathBuf::from("//{{PROJECT_NAME}}_nested/file.h.tmpl-cpp"),
                            content: "#include \"{{PROJECT_PATH}}/file.h\"\n// `fx create {{PROJECT_TYPE}}`"
                                .to_string(),
                        }),
                    );
                    entries
                })),
            );
            entries
        });

        let mut handlebars = Handlebars::new();
        handlebars.set_strict_mode(true);
        let args = TemplateArgs {
            copyright_year: "2020".to_string(),
            project_name: "foo".to_string(),
            project_path: "bar/foo".to_string(),
            project_type: "component-v2".to_string(),
        };

        let rendered =
            templates.render(&mut handlebars, &args).expect("failed to render templates");
        assert_eq!(
            rendered,
            RenderedTree::Dir({
                let mut entries = HashMap::new();
                entries.insert(
                    "file.h".to_string(),
                    Box::new(RenderedTree::File("class foo;".to_string())),
                );
                entries.insert(
                    "foo_nested".to_string(),
                    Box::new(RenderedTree::Dir({
                        let mut entries = HashMap::new();
                        entries.insert(
                            "file.h".to_string(),
                            Box::new(RenderedTree::File(
                                "#include \"bar/foo/file.h\"\n// `fx create component-v2`"
                                    .to_string(),
                            )),
                        );
                        entries
                    })),
                );
                entries
            })
        );
    }

    impl<'a> FileReader for HashMap<&'a Path, &'a str> {
        fn read_to_string(&self, path: impl AsRef<Path>) -> io::Result<String> {
            self.get(path.as_ref())
                .map(|c| c.to_string())
                .ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "file not found"))
        }
    }

    #[test]
    fn template_tree_from_file_list() {
        let mut files = HashMap::new();
        files.insert(
            Path::new("create-templates/component-v2/main.cc.tmpl-cpp"),
            r#"{{PROJECT_NAME}}"#,
        );
        let tree = TemplateTree::from_file_list(
            Path::new("create-templates"),
            &vec![PathBuf::from("component-v2/main.cc.tmpl-cpp")],
            "component-v2",
            &files,
        )
        .expect("failed");
        assert_matches!(tree, TemplateTree::Dir(nested) if nested.contains_key("main.cc"));
    }

    #[test]
    fn test_find_template_files() {
        let mut files = HashMap::new();
        files.insert(
            Path::new("create-templates/templates.json"),
            r#"[
                "_partial.tmpl",
                "component-v2/_partial.tmpl",
                "component-v2/src/main.rs.tmpl-rust",
                "component-v1/_partial.tmpl"
            ]"#,
        );
        files.insert(Path::new("create-templates/_partial.tmpl"), r#"root {{PROJECT_NAME}}"#);
        files.insert(
            Path::new("create-templates/component-v2/_partial.tmpl"),
            r#"component-v2 {{PROJECT_NAME}}"#,
        );
        files.insert(
            Path::new("create-templates/component-v2/src/main.rs.tmpl-rust"),
            r#"component-v2 {{PROJECT_NAME}}"#,
        );
        files.insert(
            Path::new("create-templates/component-v1/_partial.tmpl"),
            r#"component-v1 {{PROJECT_NAME}}"#,
        );
        let mut files = find_template_files(
            Path::new("create-templates/templates.json"),
            "component-v2",
            &Language::Rust,
            &files,
        )
        .expect("failed");

        files.sort();
        assert_eq!(
            &files,
            &[
                PathBuf::from("_partial.tmpl"),
                PathBuf::from("component-v2/_partial.tmpl"),
                PathBuf::from("component-v2/src/main.rs.tmpl-rust"),
            ],
        );
    }

    #[test]
    fn test_register_partial_templates() {
        let mut files = HashMap::new();
        files.insert(Path::new("create-templates/_partial.tmpl"), r#"root {{PROJECT_NAME}}"#);
        files.insert(
            Path::new("create-templates/component-v2/_partial.tmpl"),
            r#"component-v2 {{PROJECT_NAME}}"#,
        );
        let file_list = vec![
            PathBuf::from("_partial.tmpl"),
            PathBuf::from("component-v2/_partial.tmpl"),
            PathBuf::from("component-v2/src/main.rs.tmpl-rust"),
        ];
        let mut handlebars = Handlebars::new();
        register_partial_templates(
            &mut handlebars,
            Path::new("create-templates"),
            &file_list,
            &files,
        )
        .expect("failed");
        let registered_templates = handlebars.get_templates();
        assert!(registered_templates.contains_key("partial"));
        assert!(registered_templates.contains_key("component-v2/partial"));
        assert_eq!(registered_templates.len(), 2);

        let mut args = HashMap::new();
        args.insert("PROJECT_NAME", "foo");
        assert_eq!(
            handlebars.render_template("{{>partial}}", &args).expect("failed to render"),
            "root foo"
        );
        assert_eq!(
            handlebars
                .render_template("{{>component-v2/partial}}", &args)
                .expect("failed to render"),
            "component-v2 foo"
        );
    }
}
