// Copyright 2022 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.

use {
    anyhow::{bail, format_err, Result},
    argh::FromArgs,
    serde::{de::DeserializeOwned, Deserialize},
    serde_yaml,
    std::{
        fs::{File, OpenOptions},
        io::{stdin, stdout, BufRead, BufReader, Read, Write},
        path::PathBuf,
        process::Command,
    },
};

#[derive(FromArgs, Debug, Default, PartialEq)]
#[argh(
    description = "Creates a new RFC prepopulated with common fields.
    The command attempts to auto-populate the author sections from your git configuration.",
    example = "To create a new RFC run the following command and enter the requested information.

    You can also use options to provide values for parameters that you don't wish to provide
    interactively.

    ```
    $ fx rfc --title 'Back to the Fuchsia'
    Description: Fuchsia is a modern OS
    ...
    Area(s): 1, 2
    Issues: 123, 456
    Reviewers: foo@google.com, bar@google.com
    ```

    Your RFC markdown file and its metadata are added to //docs/contribute/governance/rfcs/",
    note = "To learn more about writing RFCs, see
    https://fuchsia.dev/fuchsia-src/contribute/governance/rfcs"
)]
pub struct CreateRfcArgs {
    /// title to use for the RFC.
    #[argh(option)]
    pub title: Option<String>,

    /// short description to use for the RFC.
    #[argh(option)]
    pub short_description: Option<String>,

    /// emails of the RFC authors.
    #[argh(option, long = "author")]
    pub authors: Vec<String>,

    /// areas of the RFC.
    #[argh(option, long = "area")]
    pub areas: Vec<String>,

    /// monorail issues associated with the RFC.
    #[argh(option, long = "issue")]
    pub issues: Vec<String>,

    /// emails of the anticipated RFC reviewers.
    #[argh(option, long = "reviewer")]
    pub reviewers: Vec<String>,
}

const AREAS_FILE: &str = "_areas.yaml";
const FX_RFC_GENERATED: &str = "<!-- Generated with `fx rfc` -->";
const META_FILE: &str = "_rfcs.yaml";
const RFC_NAME_PLACEHOLDER: &str = "RFC-NNNN";
const RFCS_PATH: &str = "docs/contribute/governance/rfcs";
const STATUS_PLACEHOLDER: &str = "Pending";
const TEMPLATE_FILE: &str = "TEMPLATE.md";
const TOC_FILE: &str = "_toc.yaml";
const TODO_COMMENT: &str = "# TODO: DO NOT SUBMIT, update.";

fn main() -> Result<(), anyhow::Error> {
    let args: CreateRfcArgs = argh::from_env();
    let handle = stdin().lock();
    let cwd = std::env::current_dir()?;
    let author_email_provider = GitConfig::new();
    rfc_impl(
        CommandLine { args, writer: &mut stdout(), reader: handle, author_email_provider },
        cwd,
    )
}

fn rfc_impl<A, R, W>(mut cli: CommandLine<'_, A, R, W>, cwd: PathBuf) -> Result<()>
where
    A: AuthorEmailProvider,
    R: BufRead,
    W: Write,
{
    let fuchsia_dir_root = get_fuchsia_dir_root(cwd)?.ok_or(format_err!(
        "This command must be run from within the Fuchsia Platform Source Tree"
    ))?;
    let rfcs_dir = fuchsia_dir_root.join(RFCS_PATH);

    let title = cli.get_title()?;
    let short_description = cli.get_short_description()?;
    let authors = cli.get_authors()?;

    let valid_areas = load_yaml::<Vec<String>>(rfcs_dir.join(AREAS_FILE))?;
    let area = cli.get_areas(valid_areas)?;
    let issue = cli.get_issues()?;
    let reviewers = cli.get_reviewers()?;

    let file = filename_from_title(&title);

    let toc_meta = TocMetadata {
        title: format!("{}: {}", RFC_NAME_PLACEHOLDER, title),
        path: format!("/{}/{}", RFCS_PATH, file),
    };
    let mut rfc_meta = RfcMetadata {
        name: RFC_NAME_PLACEHOLDER.to_string(),
        title,
        short_description,
        authors,
        file,
        area,
        issue,
        reviewers,
        status: STATUS_PLACEHOLDER.to_string(),
        gerrit_change_id: vec![],
        submitted: String::new(),
        reviewed: String::new(),
    };

    rfc_meta.sort();

    create_rfc(&rfc_meta, &rfcs_dir)?;
    append_rfc_meta(rfc_meta, rfcs_dir.join(META_FILE))?;
    append_rfc_meta(toc_meta, rfcs_dir.join(TOC_FILE))?;

    Ok(())
}

struct CommandLine<'a, A, R, W> {
    args: CreateRfcArgs,
    author_email_provider: A,
    reader: R,
    writer: &'a mut W,
}

impl<'a, A, R, W> CommandLine<'a, A, R, W>
where
    W: Write,
    R: BufRead,
    A: AuthorEmailProvider,
{
    pub fn get_title(&mut self) -> Result<String> {
        match &self.args.title {
            Some(title) => Ok(title.clone()),
            None => self.prompt("Title"),
        }
    }

    pub fn get_short_description(&mut self) -> Result<String> {
        match &self.args.short_description {
            Some(description) => Ok(description.clone()),
            None => self.prompt("Short description"),
        }
    }

    pub fn get_authors(&mut self) -> Result<Vec<String>> {
        let default_author = self.author_email_provider.get_email().ok();
        let mut authors = self.strings_or_prompt(
            self.args.authors.clone(),
            format!(
                "Authors (comma-separated){}",
                default_author.as_ref().map(|a| format!(" [default: {}]", a)).unwrap_or_default()
            ),
        )?;
        if authors.is_empty() && default_author.is_some() {
            authors.push(default_author.unwrap());
        }
        Ok(authors)
    }

    pub fn get_areas(&mut self, valid_areas: Vec<String>) -> Result<Vec<String>> {
        if self.args.areas.is_empty() {
            return self.request_areas(valid_areas);
        }
        let args_areas_len = self.args.areas.len();
        let input_areas =
            self.args.areas.clone().into_iter().map(|a| a.to_lowercase()).collect::<Vec<_>>();
        let areas_found = valid_areas
            .iter()
            .filter(|a| input_areas.contains(&a.to_lowercase()))
            .cloned()
            .collect::<Vec<_>>();
        if areas_found.len() == args_areas_len {
            Ok(areas_found)
        } else {
            self.println("Invalid areas provided. Please select valid ones.")?;
            self.request_areas(valid_areas)
        }
    }

    pub fn get_issues(&mut self) -> Result<Vec<String>> {
        self.strings_or_prompt(self.args.issues.clone(), "Monorail issue (comma-separated)")
    }

    pub fn get_reviewers(&mut self) -> Result<Vec<String>> {
        self.strings_or_prompt(self.args.reviewers.clone(), "Reviewers (comma-separated emails)")
    }

    fn strings_or_prompt(
        &mut self,
        list: Vec<String>,
        prompt: impl AsRef<str>,
    ) -> Result<Vec<String>> {
        if list.is_empty() {
            let input = self.prompt(prompt)?;
            if input.trim().is_empty() {
                return Ok(vec![]);
            }
            Ok(string_list(input))
        } else {
            Ok(list)
        }
    }

    fn request_areas(&mut self, valid_areas: Vec<String>) -> Result<Vec<String>> {
        for (i, area) in valid_areas.iter().enumerate() {
            self.println(format!("[{:>2}] {}", i, area))?;
        }
        let areas =
            areas_from_numbers(valid_areas, self.prompt("Area (comma-separated numbers)")?)?;
        Ok(areas)
    }

    fn prompt(&mut self, text: impl AsRef<str>) -> Result<String> {
        write!(&mut self.writer, "{}: ", text.as_ref())?;
        self.writer.flush().unwrap();
        let mut line = String::new();
        self.reader.read_line(&mut line)?;
        Ok(line.trim().to_string())
    }

    fn println(&mut self, text: impl AsRef<str>) -> Result<()> {
        writeln!(&mut self.writer, "{}", text.as_ref())?;
        Ok(())
    }
}

// Note: not using serde_yaml since we have a bit of a special formatting for arrays. It doesn't
// seem that serde_yaml supports formatting arrays as `[]` like we do in our YAML files. Using
// serde_yaml would require updating the format of our YAML files, in particular _rfcs.yaml.
trait AppendYaml {
    fn append_yaml(&self, w: impl Write) -> Result<()>;
}

struct RfcMetadata {
    name: String,
    title: String,
    short_description: String,
    authors: Vec<String>,
    file: String,
    area: Vec<String>,
    issue: Vec<String>,
    gerrit_change_id: Vec<String>,
    status: String,
    reviewers: Vec<String>,
    submitted: String,
    reviewed: String,
}

impl RfcMetadata {
    fn sort(&mut self) {
        self.authors.sort();
        self.area.sort();
        self.issue.sort();
        self.gerrit_change_id.sort();
        self.reviewers.sort();
    }
}

impl AppendYaml for RfcMetadata {
    fn append_yaml(&self, mut w: impl Write) -> Result<()> {
        w.write_all(b"\n")?;
        write_one(&mut w, 0, "- name", &self.name, "'", true)?;
        write_one(&mut w, 2, "title", &self.title, "'", self.title.is_empty())?;
        write_one(
            &mut w,
            2,
            "short_description",
            &self.short_description,
            "'",
            self.short_description.is_empty(),
        )?;
        write_list(&mut w, 2, "authors", &self.authors)?;
        write_one(&mut w, 2, "file", &self.file, "'", false)?;
        write_list(&mut w, 2, "area", &self.area)?;
        write_list(&mut w, 2, "issue", &self.issue)?;
        write_list(&mut w, 2, "gerrit_change_id", &self.gerrit_change_id)?;
        write_one(&mut w, 2, "status", &self.status, "'", true)?;
        write_list(&mut w, 2, "reviewers", &self.reviewers)?;
        write_one(&mut w, 2, "submitted", &self.submitted, "'", true)?;
        write_one(&mut w, 2, "reviewed", &self.reviewed, "'", true)?;
        Ok(())
    }
}

#[derive(Deserialize)]
struct TocMetadata {
    title: String,
    path: String,
}

impl AppendYaml for TocMetadata {
    fn append_yaml(&self, mut w: impl Write) -> Result<()> {
        write_one(&mut w, 2, "- title", &self.title, "\"", true)?;
        write_one(&mut w, 4, "path", &self.path, "", true)?;
        Ok(())
    }
}

trait AuthorEmailProvider {
    fn get_email(&self) -> Result<String>;
}

struct GitConfig {}
impl GitConfig {
    fn new() -> Self {
        Self {}
    }
}

impl AuthorEmailProvider for GitConfig {
    fn get_email(&self) -> Result<String> {
        let result = Command::new("sh").arg("-c").arg("git config --get user.email").output()?;
        Ok(String::from_utf8(result.stdout)?.trim().to_string())
    }
}

fn write_one<T, W>(
    w: &mut W,
    spaces: usize,
    prefix: &str,
    value: T,
    quote_char: &str,
    comment: bool,
) -> Result<()>
where
    W: Write,
    T: std::fmt::Display,
{
    write!(w, "{}{}: {}{}{}", " ".repeat(spaces), prefix, quote_char, value, quote_char)?;
    if comment {
        writeln!(w, "  {}", TODO_COMMENT)?;
    } else {
        write!(w, "\n")?;
    }
    Ok(())
}

fn write_list<T, W>(w: &mut W, spaces: usize, prefix: &str, list: &[T]) -> Result<()>
where
    W: Write,
    T: std::fmt::Display,
{
    write!(w, "{}{}: [", " ".repeat(spaces), prefix)?;
    for (i, item) in list.iter().enumerate() {
        write!(w, "'{}'", item)?;
        if i < list.len() - 1 {
            write!(w, ", ")?;
        }
    }
    if list.is_empty() {
        writeln!(w, "'']  {}", TODO_COMMENT)?;
    } else {
        writeln!(w, "]")?;
    }
    Ok(())
}

fn filename_from_title(title: &str) -> String {
    let filename = format!(
        "NNNN_{}.md",
        title.to_lowercase().split(' ').map(|s| s.trim()).collect::<Vec<_>>().join("_"),
    );
    filename.replace(std::path::is_separator, "_")
}

fn areas_from_numbers(valid_areas: Vec<String>, input_numbers: String) -> Result<Vec<String>> {
    let indexes = input_numbers
        .split(',')
        .map(|s| s.trim().parse::<usize>())
        .collect::<Result<Vec<usize>, _>>()
        .map_err(|_| format_err!("Invalid area index found"))?;
    if !indexes.iter().all(|i| *i < valid_areas.len()) {
        bail!("Invalid area indexes");
    }
    Ok(indexes.into_iter().map(|i| valid_areas[i].clone()).collect())
}

fn string_list(input_authors: String) -> Vec<String> {
    input_authors.split(',').map(|s| s.trim().to_string()).collect()
}

fn get_fuchsia_dir_root(current_dir: PathBuf) -> Result<Option<PathBuf>> {
    let mut current_dir = current_dir;
    loop {
        let jiri_root_path = current_dir.join(".jiri_root/");
        if jiri_root_path.exists() {
            return Ok(Some(current_dir));
        }
        if !current_dir.pop() {
            break;
        }
    }
    Ok(None)
}

fn load_yaml<T>(path: PathBuf) -> Result<T>
where
    T: DeserializeOwned,
{
    let file = File::open(path)?;
    let reader = BufReader::new(file);
    Ok(serde_yaml::from_reader(reader).expect("can read yaml"))
}

fn append_rfc_meta<T>(data: T, path: PathBuf) -> Result<()>
where
    T: AppendYaml,
{
    let file = OpenOptions::new().write(true).append(true).open(path)?;
    data.append_yaml(file)?;
    Ok(())
}

fn create_rfc(meta: &RfcMetadata, path: &PathBuf) -> Result<()> {
    let mut template_file = File::open(path.join(TEMPLATE_FILE))?;
    let mut template = String::new();
    template_file.read_to_string(&mut template)?;

    let template = template.replace(
        r#"{% set rfcid = "RFC-0000" %}"#,
        r#"{% set rfcid = "RFC-NNNN" %} <!-- TODO: DO NOT SUBMIT, update number -->"#,
    );

    let reviewers =
        meta.reviewers.iter().map(|r| format!("- {}", r)).collect::<Vec<_>>().join("\n");

    let reviewers_index = template.find("_Reviewers:_").unwrap();
    let consulted_index = template.find("_Consulted:_").unwrap();
    let template = format!(
        "{}\n{}_Reviewers:_\n\n{}\n\n{}",
        FX_RFC_GENERATED,
        &template[..reviewers_index],
        reviewers,
        &template[consulted_index..]
    );

    let mut rfc_file = File::create(path.join(&meta.file))?;
    rfc_file.write_all(template.as_bytes())?;
    Ok(())
}

#[cfg(test)]
mod test {
    use super::*;
    use pretty_assertions::assert_eq;
    use std::fs;
    use tempfile::{tempdir, TempDir};

    const CMD_NAME: &'static [&'static str] = &["rfc"];

    struct FakeEmailProvider {}

    impl AuthorEmailProvider for FakeEmailProvider {
        fn get_email(&self) -> Result<String> {
            Ok("fuchsia-hacker@google.com".to_string())
        }
    }

    struct FakeDir {
        root: TempDir,
        rfcs_path: PathBuf,
    }

    impl FakeDir {
        pub fn new() -> Self {
            let root = tempdir().expect("create tempdir");
            let rfcs_path = root.path().join(RFCS_PATH);
            fs::create_dir_all(&rfcs_path).expect("create root");

            fs::create_dir_all(root.path().join(".jiri_root")).expect("create .jiri_root");
            init_file(rfcs_path.join(META_FILE), include_str!("../test_data/rfcs.before.yaml"));
            init_file(rfcs_path.join(TOC_FILE), include_str!("../test_data/toc.before.yaml"));
            init_file(rfcs_path.join(AREAS_FILE), include_str!("../test_data/areas.yaml"));
            init_file(
                rfcs_path.join(TEMPLATE_FILE),
                include_str!("../../../docs/contribute/governance/rfcs/TEMPLATE.md"),
            );
            Self { root, rfcs_path }
        }

        pub fn some_path(&self) -> PathBuf {
            let path = self.root.path().join("some/path");
            fs::create_dir_all(&path).expect("create some path");
            path
        }

        pub fn rfc_file_exists(&self, file: &str) -> bool {
            self.rfcs_path.join(file).exists()
        }

        pub fn validate_rfcs_file(&self, file: &str, expected: &str) {
            let path = self.rfcs_path.join(file);
            let mut file = File::open(&path).expect(&format!("open: {}", path.display()));
            let mut contents = String::new();
            file.read_to_string(&mut contents).expect(&format!("read file: {}", path.display()));
            assert_eq!(contents, expected);
        }
    }

    fn init_file(path: PathBuf, contents: &str) {
        let mut file = File::create(path).expect("created file");
        file.write_all(contents.as_bytes()).expect("wrote file");
    }

    fn full_args() -> CreateRfcArgs {
        CreateRfcArgs {
            title: Some("Back to the Fuchsia".to_string()),
            short_description: Some("Fuchsia is a modern OS".to_string()),
            authors: vec!["foo@google.com".to_string(), "bar@google.com".to_string()],
            areas: vec!["Pink".to_string()],
            issues: vec!["5678".to_string(), "1234".to_string()],
            reviewers: vec!["quux@google.com".to_string(), "baz@google.com".to_string()],
        }
    }

    #[test]
    fn empty_args() {
        assert_eq!(CreateRfcArgs::from_args(CMD_NAME, &[]), Ok(CreateRfcArgs::default()))
    }

    #[test]
    fn args_with_options() {
        assert_eq!(
            CreateRfcArgs::from_args(
                CMD_NAME,
                &[
                    "--title",
                    "Back to the Fuchsia",
                    "--short-description",
                    "Fuchsia is a modern OS",
                    "--author",
                    "foo@google.com",
                    "--author",
                    "bar@google.com",
                    "--area",
                    "Pink",
                    "--issue",
                    "1234",
                    "--issue",
                    "5678",
                    "--reviewer",
                    "baz@google.com",
                ]
            ),
            Ok(CreateRfcArgs {
                title: Some("Back to the Fuchsia".to_string()),
                short_description: Some("Fuchsia is a modern OS".to_string()),
                authors: vec!["foo@google.com".to_string(), "bar@google.com".to_string(),],
                areas: vec!["Pink".to_string(),],
                issues: vec!["1234".to_string(), "5678".to_string(),],
                reviewers: vec!["baz@google.com".to_string()]
            })
        );
    }

    #[test]
    fn cli_with_all_optional_args() {
        let dir = FakeDir::new();

        // When the CLI receives all parameters through arguments, we don't expect any input.
        let stdin = b"";
        let mut stdout = Vec::<u8>::new();
        let args = full_args();
        rfc_impl(
            CommandLine {
                args,
                writer: &mut stdout,
                reader: &stdin[..],
                author_email_provider: FakeEmailProvider {},
            },
            // Call this command from somewhere inside the fake fuchsia platform tree.
            dir.some_path(),
        )
        .expect("succeeds");

        // We don't expect any output when the CLI receives all parameters through arguments.
        assert!(stdout.is_empty());

        dir.validate_rfcs_file(META_FILE, include_str!("../test_data/rfcs.golden.yaml"));
        dir.validate_rfcs_file(TOC_FILE, include_str!("../test_data/toc.golden.yaml"));
        dir.validate_rfcs_file(
            "NNNN_back_to_the_fuchsia.md",
            include_str!("../test_data/rfc.golden.md"),
        );
    }

    #[test]
    fn cli_with_no_optional_args() {
        let dir = FakeDir::new();

        let stdin = vec![
            "Back to the Fuchsia",
            "Fuchsia is a modern OS",
            "foo@google.com,bar@google.com",
            "1",
            "5678, 1234",
            "quux@google.com, baz@google.com",
        ]
        .join("\n")
        .into_bytes();

        let mut stdout = Vec::<u8>::new();
        let args = CreateRfcArgs::default();
        rfc_impl(
            CommandLine {
                args,
                writer: &mut stdout,
                reader: &stdin[..],
                author_email_provider: FakeEmailProvider {},
            },
            dir.root.path().to_path_buf(),
        )
        .expect("succeeds");

        assert_eq!(
            std::str::from_utf8(&stdout).expect("stdout bytes"),
            vec![
                "Title: ",
                "Short description: ",
                "Authors (comma-separated) [default: fuchsia-hacker@google.com]: ",
                "[ 0] Magenta\n[ 1] Pink\n[ 2] Purple\n",
                "Area (comma-separated numbers): ",
                "Monorail issue (comma-separated): ",
                "Reviewers (comma-separated emails): "
            ]
            .join("")
        );

        dir.validate_rfcs_file(META_FILE, include_str!("../test_data/rfcs.golden.yaml"));
        dir.validate_rfcs_file(TOC_FILE, include_str!("../test_data/toc.golden.yaml"));
        dir.validate_rfcs_file(
            "NNNN_back_to_the_fuchsia.md",
            include_str!("../test_data/rfc.golden.md"),
        );
    }

    #[test]
    fn areas_are_validated_from_stdin() {
        let stdin = b"2";
        let mut stdout = Vec::<u8>::new();
        let args = CreateRfcArgs::default();
        let mut cli = CommandLine {
            args,
            writer: &mut stdout,
            reader: &stdin[..],
            author_email_provider: FakeEmailProvider {},
        };
        assert!(cli.get_areas(vec!["A".to_string(), "B".to_string()]).is_err());
    }

    #[test]
    fn areas_are_validated_from_args() {
        let stdin = b"1";
        let mut stdout = Vec::<u8>::new();
        let mut args = CreateRfcArgs::default();
        args.areas = vec!["C".to_string()];
        let mut cli = CommandLine {
            args,
            writer: &mut stdout,
            reader: &stdin[..],
            author_email_provider: FakeEmailProvider {},
        };
        assert_eq!(
            cli.get_areas(vec!["A".to_string(), "B".to_string()]).expect("got areas"),
            vec!["B".to_string()]
        );
        assert_eq!(
            std::str::from_utf8(&stdout).expect("valid stdout"),
            vec![
                "Invalid areas provided. Please select valid ones.",
                "[ 0] A",
                "[ 1] B",
                "Area (comma-separated numbers): ",
            ]
            .join("\n")
        );
    }

    #[test]
    fn default_author_is_set_when_no_author_given() {
        let stdin = b"";
        let mut stdout = Vec::<u8>::new();
        let mut cli = CommandLine {
            args: CreateRfcArgs::default(),
            writer: &mut stdout,
            reader: &stdin[..],
            author_email_provider: FakeEmailProvider {},
        };
        assert_eq!(
            cli.get_authors().expect("got authors"),
            vec!["fuchsia-hacker@google.com".to_string()]
        );
        assert_eq!(
            std::str::from_utf8(&stdout).expect("valid stdout"),
            "Authors (comma-separated) [default: fuchsia-hacker@google.com]: "
        );
    }

    #[test]
    fn accepts_a_title_with_slashes() {
        let dir = FakeDir::new();

        let stdin = vec!["Hello/There"].join("\n").into_bytes();

        let mut stdout = Vec::<u8>::new();
        let mut args = full_args();
        args.title = None;
        rfc_impl(
            CommandLine {
                args,
                writer: &mut stdout,
                reader: &stdin[..],
                author_email_provider: FakeEmailProvider {},
            },
            dir.root.path().to_path_buf(),
        )
        .expect("succeeds");

        assert_eq!(std::str::from_utf8(&stdout).expect("stdout bytes"), "Title: ");
        assert!(dir.rfc_file_exists("NNNN_hello_there.md"));
    }
}
