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

#[macro_use]
extern crate clap;
extern crate git2;
extern crate rayon;
extern crate reqwest;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate tempdir;

use git2::Repository;
use rayon::prelude::*;
use std::collections::HashSet;
use std::fs;
use std::io::Read;
use std::iter::FromIterator;
use std::process::Command;
use tempdir::TempDir;

// If unspecified, test this many crates
const DEFAULT_NUM: usize = 5;

#[derive(Debug, Deserialize)]
struct CrateInfo {
    id: String,
    name: String,
    downloads: u64,
    max_version: String,
    description: String,
    homepage: Option<String>,
    repository: String,
}

#[derive(Debug, Deserialize)]
struct Crates {
    crates: Vec<CrateInfo>,
}

#[derive(Debug, Eq, PartialEq)]
enum TestResult {
    Success,
    Failure,
    Excluded,
}

#[derive(Debug)]
struct CrateResult {
    id: String,
    res: TestResult,
}

fn main() {
    let matches = clap_app!(cratest =>
                  (version: "1.0")
                  (author: "Tim Kilbourn <tkilbourn@google.com>")
                  (about: "Tests the top crates from crates.io on Fuchsia")
                  (@arg num: -n +takes_value "Number of crates to test")
                  (@arg excludes: -x --exclude ... +takes_value
                        "Exclude crates whose name exactly match")
                  (@arg start: --start "Starts a Fuchsia emulator")
                  (@arg restart: --restart "Stop all Fuchsia emulators and start a new one")
                  (@arg keep: --keep "Keeps the temp dir after exiting")
                  (@arg verbose: -v --verbose "Print verbose output while performing commands")
                 ).get_matches();

    let num = value_t!(matches, "num", usize).unwrap_or(DEFAULT_NUM);
    let verbose = matches.is_present("verbose");
    let restart_emu = matches.is_present("restart");
    let start_emu = matches.is_present("start");
    let keep_tmp = matches.is_present("keep");
    let excludes = HashSet::<String>::from_iter(
        values_t!(matches, "excludes", String).unwrap_or_else(|_| Vec::new()),
    );

    println!(
        "Running cratest on the top {} crates from crates.io...",
        num
    );

    let crate_uri: String = [
        "https://crates.io/api/v1/crates?page=1&per_page=",
        &format!("{}", num),
        "&sort=downloads",
    ].join("")
        .into();

    if verbose {
        println!("Downloading crates from {}", crate_uri);
        if !excludes.is_empty() {
            println!("Excluding {} crates", excludes.len());
        }
    }
    let mut resp = reqwest::get(&crate_uri).unwrap();
    assert!(resp.status().is_success());

    let mut content = String::new();
    resp.read_to_string(&mut content).unwrap();

    let res: Crates = serde_json::from_str(&content).unwrap();

    if restart_emu {
        Command::new("fargo")
            .arg("restart")
            .status()
            .expect("failed to run fargo restart");
    } else if start_emu {
        Command::new("fargo")
            .arg("start")
            .status()
            .expect("failed to run fargo start");
    }

    let tmpdir = TempDir::new("cratest").unwrap();

    let results: Vec<CrateResult> = res.crates
        .par_iter()
        .map(|cr| {
            if excludes.contains(&cr.id) {
                if verbose {
                    println!("Skipping {} (excluded)", &cr.id);
                }
                return CrateResult {
                    id: cr.id.clone(),
                    res: TestResult::Excluded,
                };
            }
            let crdir = tmpdir.path().join(&cr.id);
            fs::create_dir(&crdir).unwrap();
            Repository::clone(&cr.repository, &crdir).unwrap();

            let output = Command::new("fargo")
                .arg("test")
                .current_dir(&crdir)
                .output()
                .expect("failed to execute fargo test");
            println!("crate: {}", &cr.id);
            println!("status: {}", output.status);
            if verbose {
                println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
                println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
            }

            CrateResult {
                id: cr.id.clone(),
                res: if output.status.success() {
                    TestResult::Success
                } else {
                    TestResult::Failure
                },
            }
        })
        .collect();

    let (succ, fail, excl) = results.into_iter().fold(
        (Vec::new(), Vec::new(), Vec::new()),
        |(mut s, mut f, mut e), r| {
            match r.res {
                TestResult::Success => s.push(r.id),
                TestResult::Failure => f.push(r.id),
                TestResult::Excluded => e.push(r.id),
            }
            (s, f, e)
        },
    );

    for &(hdr, ref results) in &[("Successes", succ), ("Failures", fail), ("Excluded", excl)] {
        if !results.is_empty() {
            println!("{}({}): {:?}", hdr, results.len(), results);
        }
    }

    if keep_tmp {
        let tmppath = tmpdir.into_path();
        println!("Temp output left at {}", tmppath.to_string_lossy());
    }
}
