// 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},
    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-0000";
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!(
        "0000_{}.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("<!--\n// LINT.IfChange\n-->\n", "");
    let template = template
        .replace("<!--\n// LINT.ThenChange(//tools/rfc/test_data/rfc.golden.md)\n-->\n", "");

    let template = template.replace(
        r#"{% set rfcid = "RFC-0000" %}"#,
        r#"{% set rfcid = "RFC-0000" %} <!-- 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).unwrap_or_else(|e| panic!("open: {}: {:?}", path.display(), e));
            let mut contents = String::new();
            file.read_to_string(&mut contents)
                .unwrap_or_else(|e| panic!("read file: {}: {:?}", path.display(), e));
            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(
            "0000_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(
            "0000_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("0000_hello_there.md"));
    }
}
