// 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::{anyhow, Result};
use argh::FromArgs;

use std::{
    env,
    fs::{self, File},
    io::{self, BufRead, BufReader},
    path::{Path, PathBuf},
    process::Command,
};

use crate::monorail::Monorail;

mod allow;
mod fix;
mod issues;
mod lint;
mod monorail;
mod owners;
mod rollout;
mod span;

#[derive(Debug, FromArgs)]
/// Silence rustc and clippy lints with allow attributes and autofixes
struct Args {
    #[argh(subcommand)]
    action: Action,
    /// don't modify source files
    #[argh(switch)]
    dryrun: bool,
    /// modify files even if there are local uncommitted changes
    #[argh(switch)]
    force: bool,
    /// lint (or category) to deal with e.g. clippy::needless_return
    #[argh(option)]
    lint: Vec<String>,
    /// the path to the rollout file
    #[argh(option)]
    rollout: Option<PathBuf>,
    /// path to the root dir of the fuchsia source tree
    #[argh(option)]
    fuchsia_dir: Option<PathBuf>,
    /// file containing json lints (uses stdin if not given)
    #[argh(positional)]
    lint_file: Option<PathBuf>,
    /// path to a prpc binary for monorail API calls
    #[argh(option)]
    prpc: Option<PathBuf>,
    /// mock monorail issue creation calls instead of calling prpc
    #[argh(switch)]
    mock: bool,
    /// print details of created issues to the command line
    #[argh(switch)]
    verbose: bool,
    /// print API calls to the command line
    #[argh(switch)]
    log_api: bool,
}

impl Args {
    pub fn try_get_filter(&self) -> Result<&[String]> {
        if self.lint.is_empty() {
            Err(anyhow!("Must filter on at least one lint or category with '--lint'"))
        } else {
            Ok(&self.lint)
        }
    }

    pub fn read_lints(&self) -> Box<dyn BufRead> {
        if let Some(ref f) = self.lint_file {
            Box::new(BufReader::new(File::open(f).unwrap()))
        } else {
            Box::new(BufReader::new(io::stdin()))
        }
    }

    pub fn monorail_api(&self) -> Result<Box<dyn Monorail>> {
        const MONORAIL_API_URL: &'static str = "api-dot-monorail-prod.appspot.com";

        let prpc = self.prpc.as_ref().map(|binary_path| {
            monorail::Prpc::new(binary_path.clone(), MONORAIL_API_URL.to_string())
        });

        if self.dryrun || self.mock {
            Ok(Box::new(monorail::Mock::new(self.log_api, prpc)))
        } else {
            Ok(Box::new(
                prpc.ok_or_else(|| anyhow!("--prpc is required when monorail is not mocked"))?,
            ))
        }
    }

    pub fn rollout_path(&self) -> &Path {
        self.rollout.as_deref().unwrap_or(Path::new("./rollout.json~"))
    }

    pub fn change_to_fuchsia_root(&self) -> Result<PathBuf> {
        if let Some(fuchsia_dir) =
            self.fuchsia_dir.clone().or_else(|| env::var("FUCHSIA_DIR").ok().map(Into::into))
        {
            env::set_current_dir(&fuchsia_dir)?;
            Ok(fuchsia_dir)
        } else {
            Ok(std::env::current_dir()?.canonicalize()?)
        }
    }
}

#[derive(Debug, FromArgs)]
#[argh(subcommand)]
enum Action {
    Fix(Fix),
    Allow(Allow),
    Rollout(Rollout),
}

/// use rustfix to auto-fix the lints
#[derive(FromArgs, Debug)]
#[argh(subcommand, name = "fix")]
struct Fix {}

/// add allow attributes
#[derive(FromArgs, Debug)]
#[argh(subcommand, name = "allow")]
struct Allow {
    /// the tag to link to on codesearch
    #[argh(option)]
    codesearch_tag: Option<String>,
    /// path to an issue description template containing "INSERT_DETAILS_HERE"
    #[argh(option)]
    template: Option<PathBuf>,
    /// the issue to mark created issues as blocking
    #[argh(option)]
    blocking_issue: Option<String>,
    /// the labels to add to created issues
    #[argh(option)]
    labels: Vec<String>,
    /// the maximum number of additional users to CC on created issues
    #[argh(option, default = "3")]
    max_cc_users: usize,
}

impl Allow {
    fn load_template(&self) -> Result<Option<String>> {
        Ok(self.template.as_ref().map(|path| fs::read_to_string(path)).transpose()?)
    }
}

/// roll out lints generated by allow
#[derive(FromArgs, Debug)]
#[argh(subcommand, name = "rollout")]
struct Rollout {}

fn main() -> Result<()> {
    let args: Args = argh::from_env();

    let git_status =
        Command::new("jiri").args(["runp", "git", "status", "--porcelain"]).output()?;
    let clean_tree = git_status.status.success() && git_status.stdout.is_empty();
    if !(args.dryrun || args.force || clean_tree) {
        return Err(anyhow!(
            "The current directory is dirty, pass the --force flag or commit the local changes"
        ));
    }

    match args.action {
        Action::Fix(_) => fix::fix(&mut args.read_lints(), args.try_get_filter()?, args.dryrun),
        Action::Allow(ref allow_args) => {
            let mut monorail = args.monorail_api()?;
            let mut issue_template = issues::IssueTemplate::new(
                &args.lint,
                allow_args.codesearch_tag.as_deref(),
                allow_args.load_template()?,
                allow_args.blocking_issue.as_deref(),
                allow_args.labels.as_ref(),
                allow_args.max_cc_users,
            );

            let rollout_path = args.rollout_path();
            if rollout_path.exists() {
                return Err(anyhow!(
                    "The rollout path {} already exists, delete it or specify an alternate path.",
                    rollout_path.to_str().unwrap_or("<non-utf8 path>"),
                ));
            }

            allow::allow(
                &mut args.read_lints(),
                args.try_get_filter()?,
                &args.change_to_fuchsia_root()?,
                &mut *monorail,
                &mut issue_template,
                rollout_path,
                args.dryrun,
                args.verbose,
            )
        }
        Action::Rollout(_) => {
            let mut monorail = args.monorail_api()?;
            let rollout_path = args.rollout_path();
            if !rollout_path.exists() {
                return Err(anyhow!(
                    "The rollout path {} does not exist, run shush allow to generate a rollout file.",
                    rollout_path.to_str().unwrap_or("<non-utf8 path>"),
                ));
            }

            rollout::rollout(&mut *monorail, rollout_path, args.verbose)
        }
    }
}
