use serde::{Deserialize, Serialize};
use build_helper::t;
use std::time;
use std::fs;
use std::io::{Seek, SeekFrom};
use std::collections::HashMap;
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
use std::fmt;
use std::process::Command;
use std::path::PathBuf;
use std::env;

// Each cycle is 42 days long (6 weeks); the last week is 35..=42 then.
const BETA_WEEK_START: u64 = 35;

#[cfg(linux)]
const OS: Option<&str> = Some("linux");

#[cfg(windows)]
const OS: Option<&str> = Some("windows");

#[cfg(all(not(linux), not(windows)))]
const OS: Option<&str> = None;

type ToolstateData = HashMap<Box<str>, ToolState>;

#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
/// Whether a tool can be compiled, tested or neither
pub enum ToolState {
    /// The tool compiles successfully, but the test suite fails
    TestFail = 1,
    /// The tool compiles successfully and its test suite passes
    TestPass = 2,
    /// The tool can't even be compiled
    BuildFail = 0,
}

impl fmt::Display for ToolState {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", match self {
            ToolState::TestFail => "test-fail",
            ToolState::TestPass => "test-pass",
            ToolState::BuildFail => "build-fail",
        })
    }
}

impl Default for ToolState {
    fn default() -> Self {
        // err on the safe side
        ToolState::BuildFail
    }
}

/// Number of days after the last promotion of beta.
/// Its value is 41 on the Tuesday where "Promote master to beta (T-2)" happens.
/// The Wednesday after this has value 0.
/// We track this value to prevent regressing tools in the last week of the 6-week cycle.
fn days_since_beta_promotion() -> u64 {
    let since_epoch = t!(time::SystemTime::UNIX_EPOCH.elapsed());
    (since_epoch.as_secs() / 86400 - 20) % 42
}

// These tools must test-pass on the beta/stable channels.
//
// On the nightly channel, their build step must be attempted, but they may not
// be able to build successfully.
static STABLE_TOOLS: &[(&str, &str)] = &[
    ("book", "src/doc/book"),
    ("nomicon", "src/doc/nomicon"),
    ("reference", "src/doc/reference"),
    ("rust-by-example", "src/doc/rust-by-example"),
    ("edition-guide", "src/doc/edition-guide"),
    ("rls", "src/tools/rls"),
    ("rustfmt", "src/tools/rustfmt"),
    ("clippy-driver", "src/tools/clippy"),
];

// These tools are permitted to not build on the beta/stable channels.
//
// We do require that we checked whether they build or not on the tools builder,
// though, as otherwise we will be unable to file an issue if they start
// failing.
static NIGHTLY_TOOLS: &[(&str, &str)] = &[
    ("miri", "src/tools/miri"),
    ("embedded-book", "src/doc/embedded-book"),
    ("rustc-guide", "src/doc/rustc-guide"),
];

fn print_error(tool: &str, submodule: &str) {
    eprintln!("");
    eprintln!("We detected that this PR updated '{}', but its tests failed.", tool);
    eprintln!("");
    eprintln!("If you do intend to update '{}', please check the error messages above and", tool);
    eprintln!("commit another update.");
    eprintln!("");
    eprintln!("If you do NOT intend to update '{}', please ensure you did not accidentally", tool);
    eprintln!("change the submodule at '{}'. You may ask your reviewer for the", submodule);
    eprintln!("proper steps.");
    std::process::exit(3);
}

fn check_changed_files(toolstates: &HashMap<Box<str>, ToolState>) {
    // Changed files
    let output = std::process::Command::new("git")
        .arg("diff")
        .arg("--name-status")
        .arg("HEAD")
        .arg("HEAD^")
        .output();
    let output = match output {
        Ok(o) => o,
        Err(e) => {
            eprintln!("Failed to get changed files: {:?}", e);
            std::process::exit(1);
        }
    };

    let output = t!(String::from_utf8(output.stdout));

    for (tool, submodule) in STABLE_TOOLS.iter().chain(NIGHTLY_TOOLS.iter()) {
        let changed = output.lines().any(|l| {
            l.starts_with("M") && l.ends_with(submodule)
        });
        eprintln!("Verifying status of {}...", tool);
        if !changed {
            continue;
        }

        eprintln!("This PR updated '{}', verifying if status is 'test-pass'...", submodule);
        if toolstates[*tool] != ToolState::TestPass {
            print_error(tool, submodule);
        }
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct ToolStateCheck;

impl Step for ToolStateCheck {
    type Output = ();

    /// Runs the `linkchecker` tool as compiled in `stage` by the `host` compiler.
    ///
    /// This tool in `src/tools` will verify the validity of all our links in the
    /// documentation to ensure we don't have a bunch of dead ones.
    fn run(self, builder: &Builder<'_>) {
        if builder.config.dry_run {
            return;
        }

        let days_since_beta_promotion = days_since_beta_promotion();
        let in_beta_week = days_since_beta_promotion >= BETA_WEEK_START;
        let is_nightly = !(builder.config.channel == "beta" || builder.config.channel == "stable");
        let toolstates = builder.toolstates();

        let mut did_error = false;

        for (tool, _) in STABLE_TOOLS.iter().chain(NIGHTLY_TOOLS.iter()) {
            if !toolstates.contains_key(*tool) {
                did_error = true;
                eprintln!("error: Tool `{}` was not recorded in tool state.", tool);
            }
        }

        if did_error {
            std::process::exit(1);
        }

        check_changed_files(&toolstates);

        for (tool, _) in STABLE_TOOLS.iter() {
            let state = toolstates[*tool];

            if state != ToolState::TestPass {
                if !is_nightly {
                    did_error = true;
                    eprintln!("error: Tool `{}` should be test-pass but is {}", tool, state);
                } else if in_beta_week {
                    did_error = true;
                    eprintln!("error: Tool `{}` should be test-pass but is {} during beta week.",
                        tool, state);
                }
            }
        }

        if did_error {
            std::process::exit(1);
        }

        if builder.config.channel == "nightly" && env::var_os("TOOLSTATE_PUBLISH").is_some() {
            commit_toolstate_change(&toolstates, in_beta_week);
        }
    }

    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
        run.path("check-tools")
    }

    fn make_run(run: RunConfig<'_>) {
        run.builder.ensure(ToolStateCheck);
    }
}

impl Builder<'_> {
    fn toolstates(&self) -> HashMap<Box<str>, ToolState> {
        if let Some(ref path) = self.config.save_toolstates {
            if let Some(parent) = path.parent() {
                // Ensure the parent directory always exists
                t!(std::fs::create_dir_all(parent));
            }
            let mut file = t!(fs::OpenOptions::new()
                .create(true)
                .write(true)
                .read(true)
                .open(path));

            serde_json::from_reader(&mut file).unwrap_or_default()
        } else {
            Default::default()
        }
    }

    /// Updates the actual toolstate of a tool.
    ///
    /// The toolstates are saved to the file specified by the key
    /// `rust.save-toolstates` in `config.toml`. If unspecified, nothing will be
    /// done. The file is updated immediately after this function completes.
    pub fn save_toolstate(&self, tool: &str, state: ToolState) {
        if let Some(ref path) = self.config.save_toolstates {
            if let Some(parent) = path.parent() {
                // Ensure the parent directory always exists
                t!(std::fs::create_dir_all(parent));
            }
            let mut file = t!(fs::OpenOptions::new()
                .create(true)
                .read(true)
                .write(true)
                .open(path));

            let mut current_toolstates: HashMap<Box<str>, ToolState> =
                serde_json::from_reader(&mut file).unwrap_or_default();
            current_toolstates.insert(tool.into(), state);
            t!(file.seek(SeekFrom::Start(0)));
            t!(file.set_len(0));
            t!(serde_json::to_writer(file, &current_toolstates));
        }
    }
}

/// This function `commit_toolstate_change` provides functionality for pushing a change
/// to the `rust-toolstate` repository.
///
/// The function relies on a GitHub bot user, which should have a Personal access
/// token defined in the environment variable $TOOLSTATE_REPO_ACCESS_TOKEN. If for
/// some reason you need to change the token, please update the Azure Pipelines
/// variable group.
///
///   1. Generate a new Personal access token:
///
///       * Login to the bot account, and go to Settings -> Developer settings ->
///           Personal access tokens
///       * Click "Generate new token"
///       * Enable the "public_repo" permission, then click "Generate token"
///       * Copy the generated token (should be a 40-digit hexadecimal number).
///           Save it somewhere secure, as the token would be gone once you leave
///           the page.
///
///   2. Update the variable group in Azure Pipelines
///
///       * Ping a member of the infrastructure team to do this.
///
///   4. Replace the email address below if the bot account identity is changed
///
///       * See <https://help.github.com/articles/about-commit-email-addresses/>
///           if a private email by GitHub is wanted.
fn commit_toolstate_change(
    current_toolstate: &ToolstateData,
    in_beta_week: bool,
) {
    fn git_config(key: &str, value: &str) {
        let status = Command::new("git").arg("config").arg("--global").arg(key).arg(value).status();
        let success = match status {
            Ok(s) => s.success(),
            Err(_) => false,
        };
        if !success {
            panic!("git config key={} value={} successful (status: {:?})", key, value, status);
        }
    }

    git_config("user.email", "7378925+rust-toolstate-update@users.noreply.github.com");
    git_config("user.name", "Rust Toolstate Update");
    git_config("credential.helper", "store");

    let credential = format!(
        "https://{}:x-oauth-basic@github.com\n",
        t!(env::var("TOOLSTATE_REPO_ACCESS_TOKEN")),
    );
    let git_credential_path = PathBuf::from(t!(env::var("HOME"))).join(".git-credentials");
    t!(fs::write(&git_credential_path, credential));

    let status = Command::new("git").arg("clone")
        .arg("--depth=1")
        .arg(t!(env::var("TOOLSTATE_REPO")))
        .status();
    let success = match status {
        Ok(s) => s.success(),
        Err(_) => false,
    };
    if !success {
        panic!("git clone successful (status: {:?})", status);
    }

    let old_toolstate = t!(fs::read("rust-toolstate/_data/latest.json"));
    let old_toolstate: Vec<RepoState> = t!(serde_json::from_slice(&old_toolstate));

    let message = format!("({} CI update)", OS.expect("linux/windows only"));
    let mut success = false;
    for _ in 1..=5 {
        // Update the toolstate results (the new commit-to-toolstate mapping) in the toolstate repo.
        change_toolstate(&current_toolstate, &old_toolstate, in_beta_week);

        // `git commit` failing means nothing to commit.
        let status = t!(Command::new("git")
            .current_dir("rust-toolstate")
            .arg("commit")
            .arg("-a")
            .arg("-m")
            .arg(&message)
            .status());
        if !status.success() {
            success = true;
            break;
        }

        let status = t!(Command::new("git")
            .current_dir("rust-toolstate")
            .arg("push")
            .arg("origin")
            .arg("master")
            .status());
        // If we successfully push, exit.
        if status.success() {
            success = true;
            break;
        }
        eprintln!("Sleeping for 3 seconds before retrying push");
        std::thread::sleep(std::time::Duration::from_secs(3));
        let status = t!(Command::new("git")
            .current_dir("rust-toolstate")
            .arg("fetch")
            .arg("origin")
            .arg("master")
            .status());
        assert!(status.success());
        let status = t!(Command::new("git")
            .current_dir("rust-toolstate")
            .arg("reset")
            .arg("--hard")
            .arg("origin/master")
            .status());
        assert!(status.success());
    }

    if !success {
        panic!("Failed to update toolstate repository with new data");
    }
}

fn change_toolstate(
    current_toolstate: &ToolstateData,
    old_toolstate: &[RepoState],
    in_beta_week: bool,
) {
    let mut regressed = false;
    for repo_state in old_toolstate {
        let tool = &repo_state.tool;
        let state = if cfg!(linux) {
            &repo_state.linux
        } else if cfg!(windows) {
            &repo_state.windows
        } else {
            unimplemented!()
        };
        let new_state = current_toolstate[tool.as_str()];

        if new_state != *state {
            eprintln!("The state of `{}` has changed from `{}` to `{}`", tool, state, new_state);
            if (new_state as u8) < (*state as u8) {
                if !["rustc-guide", "miri", "embedded-book"].contains(&tool.as_str()) {
                    regressed = true;
                }
            }
        }
    }

    if regressed && in_beta_week {
        std::process::exit(1);
    }

    let commit = t!(std::process::Command::new("git")
        .arg("rev-parse")
        .arg("HEAD")
        .output());
    let commit = t!(String::from_utf8(commit.stdout));

    let toolstate_serialized = t!(serde_json::to_string(&current_toolstate));

    let history_path = format!("rust-toolstate/history/{}.tsv", OS.expect("linux/windows only"));
    let mut file = t!(fs::read_to_string(&history_path));
    let end_of_first_line = file.find('\n').unwrap();
    file.insert_str(end_of_first_line, &format!("{}\t{}\n", commit, toolstate_serialized));
    t!(fs::write(&history_path, file));
}

#[derive(Debug, Serialize, Deserialize)]
struct RepoState {
    tool: String,
    windows: ToolState,
    linux: ToolState,
    commit: String,
    datetime: String,
}
