use std::env;
use std::error::Error;
use std::ffi::OsStr;
use std::fmt;
use std::fs;
use std::io::prelude::*;
use std::os;
use std::path::{Path, PathBuf};
use std::process::Output;
use std::str;
use std::usize;

use rustc_serialize::json::Json;
use url::Url;
use hamcrest as ham;
use cargo::util::ProcessBuilder;
use cargo::util::ProcessError;

use support::paths::CargoPathExt;

#[macro_export]
macro_rules! t {
    ($e:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed with {}", stringify!($e), e),
    })
}

pub mod paths;
pub mod git;
pub mod registry;

/*
 *
 * ===== Builders =====
 *
 */

#[derive(PartialEq,Clone)]
struct FileBuilder {
    path: PathBuf,
    body: String
}

impl FileBuilder {
    pub fn new(path: PathBuf, body: &str) -> FileBuilder {
        FileBuilder { path: path, body: body.to_string() }
    }

    fn mk(&self) {
        self.dirname().mkdir_p();

        let mut file = fs::File::create(&self.path).unwrap_or_else(|e| {
            panic!("could not create file {}: {}", self.path.display(), e)
        });

        t!(file.write_all(self.body.as_bytes()));
    }

    fn dirname(&self) -> &Path {
        self.path.parent().unwrap()
    }
}

#[derive(PartialEq,Clone)]
struct SymlinkBuilder {
    dst: PathBuf,
    src: PathBuf,
}

impl SymlinkBuilder {
    pub fn new(dst: PathBuf, src: PathBuf) -> SymlinkBuilder {
        SymlinkBuilder { dst: dst, src: src }
    }

    #[cfg(unix)]
    fn mk(&self) {
        self.dirname().mkdir_p();
        t!(os::unix::fs::symlink(&self.dst, &self.src));
    }

    #[cfg(windows)]
    fn mk(&self) {
        self.dirname().mkdir_p();
        t!(os::windows::fs::symlink_file(&self.dst, &self.src));
    }

    fn dirname(&self) -> &Path {
        self.src.parent().unwrap()
    }
}

#[derive(PartialEq,Clone)]
pub struct ProjectBuilder {
    name: String,
    root: PathBuf,
    files: Vec<FileBuilder>,
    symlinks: Vec<SymlinkBuilder>
}

impl ProjectBuilder {
    pub fn new(name: &str, root: PathBuf) -> ProjectBuilder {
        ProjectBuilder {
            name: name.to_string(),
            root: root,
            files: vec![],
            symlinks: vec![]
        }
    }

    pub fn root(&self) -> PathBuf {
        self.root.clone()
    }

    pub fn url(&self) -> Url { path2url(self.root()) }

    pub fn bin(&self, b: &str) -> PathBuf {
        self.build_dir().join("debug").join(&format!("{}{}", b,
                                                     env::consts::EXE_SUFFIX))
    }

    pub fn release_bin(&self, b: &str) -> PathBuf {
        self.build_dir().join("release").join(&format!("{}{}", b,
                                                       env::consts::EXE_SUFFIX))
    }

    pub fn target_bin(&self, target: &str, b: &str) -> PathBuf {
        self.build_dir().join(target).join("debug")
                        .join(&format!("{}{}", b, env::consts::EXE_SUFFIX))
    }

    pub fn build_dir(&self) -> PathBuf {
        self.root.join("target")
    }

    pub fn process<T: AsRef<OsStr>>(&self, program: T) -> ProcessBuilder {
        let mut p = ::process(program);
        p.cwd(self.root());
        return p
    }

    pub fn cargo(&self, cmd: &str) -> ProcessBuilder {
        let mut p = self.process(&cargo_dir().join("cargo"));
        p.arg(cmd);
        return p;
    }

    pub fn cargo_process(&self, cmd: &str) -> ProcessBuilder {
        self.build();
        self.cargo(cmd)
    }

    pub fn file<B: AsRef<Path>>(mut self, path: B,
                                body: &str) -> ProjectBuilder {
        self.files.push(FileBuilder::new(self.root.join(path), body));
        self
    }

    pub fn symlink<T: AsRef<Path>>(mut self, dst: T,
                                   src: T) -> ProjectBuilder {
        self.symlinks.push(SymlinkBuilder::new(self.root.join(dst),
                                               self.root.join(src)));
        self
    }

    // TODO: return something different than a ProjectBuilder
    pub fn build(&self) -> &ProjectBuilder {
        // First, clean the directory if it already exists
        self.rm_root();

        // Create the empty directory
        self.root.mkdir_p();

        for file in self.files.iter() {
            file.mk();
        }

        for symlink in self.symlinks.iter() {
            symlink.mk();
        }
        self
    }

    pub fn read_lockfile(&self) -> String {
        let mut buffer = String::new();
        fs::File::open(self.root().join("Cargo.lock")).unwrap()
            .read_to_string(&mut buffer).unwrap();
        buffer
    }

    fn rm_root(&self) {
        self.root.rm_rf()
    }
}

// Generates a project layout
pub fn project(name: &str) -> ProjectBuilder {
    ProjectBuilder::new(name, paths::root().join(name))
}

// Generates a project layout inside our fake home dir
pub fn project_in_home(name: &str) -> ProjectBuilder {
    ProjectBuilder::new(name, paths::home().join(name))
}

// === Helpers ===

pub fn main_file(println: &str, deps: &[&str]) -> String {
    let mut buf = String::new();

    for dep in deps.iter() {
        buf.push_str(&format!("extern crate {};\n", dep));
    }

    buf.push_str("fn main() { println!(");
    buf.push_str(&println);
    buf.push_str("); }\n");

    buf.to_string()
}

trait ErrMsg<T> {
    fn with_err_msg(self, val: String) -> Result<T, String>;
}

impl<T, E: fmt::Display> ErrMsg<T> for Result<T, E> {
    fn with_err_msg(self, val: String) -> Result<T, String> {
        match self {
            Ok(val) => Ok(val),
            Err(err) => Err(format!("{}; original={}", val, err))
        }
    }
}

// Path to cargo executables
pub fn cargo_dir() -> PathBuf {
    env::var_os("CARGO_BIN_PATH").map(PathBuf::from).or_else(|| {
        env::current_exe().ok().map(|mut path| {
            path.pop();
            if path.ends_with("deps") {
                path.pop();
            }
            path
        })
    }).unwrap_or_else(|| {
        panic!("CARGO_BIN_PATH wasn't set. Cannot continue running test")
    })
}

/// Returns an absolute path in the filesystem that `path` points to. The
/// returned path does not contain any symlinks in its hierarchy.
/*
 *
 * ===== Matchers =====
 *
 */

#[derive(Clone)]
pub struct Execs {
    expect_stdout: Option<String>,
    expect_stdin: Option<String>,
    expect_stderr: Option<String>,
    expect_exit_code: Option<i32>,
    expect_stdout_contains: Vec<String>,
    expect_stderr_contains: Vec<String>,
    expect_json: Option<Vec<Json>>,
}

impl Execs {
    pub fn with_stdout<S: ToString>(mut self, expected: S) -> Execs {
        self.expect_stdout = Some(expected.to_string());
        self
    }

    pub fn with_stderr<S: ToString>(mut self, expected: S) -> Execs {
        self.expect_stderr = Some(expected.to_string());
        self
    }

    pub fn with_status(mut self, expected: i32) -> Execs {
        self.expect_exit_code = Some(expected);
        self
    }

    pub fn with_stdout_contains<S: ToString>(mut self, expected: S) -> Execs {
        self.expect_stdout_contains.push(expected.to_string());
        self
    }

    pub fn with_stderr_contains<S: ToString>(mut self, expected: S) -> Execs {
        self.expect_stderr_contains.push(expected.to_string());
        self
    }

    pub fn with_json(mut self, expected: &str) -> Execs {
        self.expect_json = Some(expected.split("\n\n").map(|obj| {
            Json::from_str(obj).unwrap()
        }).collect());
        self
    }

    fn match_output(&self, actual: &Output) -> ham::MatchResult {
        self.match_status(actual)
            .and(self.match_stdout(actual))
            .and(self.match_stderr(actual))
    }

    fn match_status(&self, actual: &Output) -> ham::MatchResult {
        match self.expect_exit_code {
            None => ham::success(),
            Some(code) => {
                ham::expect(
                    actual.status.code() == Some(code),
                    format!("exited with {}\n--- stdout\n{}\n--- stderr\n{}",
                            actual.status,
                            String::from_utf8_lossy(&actual.stdout),
                            String::from_utf8_lossy(&actual.stderr)))
            }
        }
    }

    fn match_stdout(&self, actual: &Output) -> ham::MatchResult {
        self.match_std(self.expect_stdout.as_ref(), &actual.stdout,
                       "stdout", &actual.stderr, false)?;
        for expect in self.expect_stdout_contains.iter() {
            self.match_std(Some(expect), &actual.stdout, "stdout",
                           &actual.stderr, true)?;
        }
        for expect in self.expect_stderr_contains.iter() {
            self.match_std(Some(expect), &actual.stderr, "stderr",
                           &actual.stdout, true)?;
        }

        if let Some(ref objects) = self.expect_json {
            let lines = match str::from_utf8(&actual.stdout) {
                Err(..) => return Err("stdout was not utf8 encoded".to_owned()),
                Ok(stdout) => stdout.lines().collect::<Vec<_>>(),
            };
            if lines.len() != objects.len() {
                return Err(format!("expected {} json lines, got {}",
                                   objects.len(), lines.len()));
            }
            for (obj, line) in objects.iter().zip(lines) {
                self.match_json(obj, line)?;
            }
        }
        Ok(())
    }

    fn match_stderr(&self, actual: &Output) -> ham::MatchResult {
        self.match_std(self.expect_stderr.as_ref(), &actual.stderr,
                       "stderr", &actual.stdout, false)
    }

    fn match_std(&self, expected: Option<&String>, actual: &[u8],
                 description: &str, extra: &[u8],
                 partial: bool) -> ham::MatchResult {
        let out = match expected {
            Some(out) => out,
            None => return ham::success(),
        };
        let actual = match str::from_utf8(actual) {
            Err(..) => return Err(format!("{} was not utf8 encoded",
                                       description)),
            Ok(actual) => actual,
        };
        // Let's not deal with \r\n vs \n on windows...
        let actual = actual.replace("\r", "");
        let actual = actual.replace("\t", "<tab>");

        let mut a = actual.lines();
        let e = out.lines();

        if partial {
            let mut diffs = self.diff_lines(a.clone(), e.clone(), partial);
            while let Some(..) = a.next() {
                let a = self.diff_lines(a.clone(), e.clone(), partial);
                if a.len() < diffs.len() {
                    diffs = a;
                }
            }
            ham::expect(diffs.is_empty(),
                        format!("expected to find:\n\
                                 {}\n\n\
                                 did not find in output:\n\
                                 {}", out,
                                 actual))
        } else {
            let diffs = self.diff_lines(a, e, partial);
            ham::expect(diffs.is_empty(),
                        format!("differences:\n\
                                {}\n\n\
                                other output:\n\
                                `{}`", diffs.join("\n"),
                                String::from_utf8_lossy(extra)))
        }

    }

    fn match_json(&self, expected: &Json, line: &str) -> ham::MatchResult {
        let actual = match Json::from_str(line) {
             Err(e) => return Err(format!("invalid json, {}:\n`{}`", e, line)),
             Ok(actual) => actual,
        };

        match find_mismatch(expected, &actual) {
            Some((expected_part, actual_part)) => Err(format!(
                "JSON mismatch\nExpected:\n{}\nWas:\n{}\nExpected part:\n{}\nActual part:\n{}\n",
                expected.pretty(), actual.pretty(),
                expected_part.pretty(), actual_part.pretty()
            )),
            None => Ok(()),
        }
    }

    fn diff_lines<'a>(&self, actual: str::Lines<'a>, expected: str::Lines<'a>,
                      partial: bool) -> Vec<String> {
        let actual = actual.take(if partial {
            expected.clone().count()
        } else {
            usize::MAX
        });
        zip_all(actual, expected).enumerate().filter_map(|(i, (a,e))| {
            match (a, e) {
                (Some(a), Some(e)) => {
                    if lines_match(&e, &a) {
                        None
                    } else {
                        Some(format!("{:3} - |{}|\n    + |{}|\n", i, e, a))
                    }
                },
                (Some(a), None) => {
                    Some(format!("{:3} -\n    + |{}|\n", i, a))
                },
                (None, Some(e)) => {
                    Some(format!("{:3} - |{}|\n    +\n", i, e))
                },
                (None, None) => panic!("Cannot get here")
            }
        }).collect()
    }
}

pub fn lines_match(expected: &str, mut actual: &str) -> bool {
    let expected = substitute_macros(expected);
    for (i, part) in expected.split("[..]").enumerate() {
        match actual.find(part) {
            Some(j) => {
                if i == 0 && j != 0 {
                    return false
                }
                actual = &actual[j + part.len()..];
            }
            None => {
                return false
            }
        }
    }
    actual.is_empty() || expected.ends_with("[..]")
}

#[test]
fn lines_match_works() {
    assert!(lines_match("a b", "a b"));
    assert!(lines_match("a[..]b", "a b"));
    assert!(lines_match("a[..]", "a b"));
    assert!(lines_match("[..]", "a b"));
    assert!(lines_match("[..]b", "a b"));

    assert!(!lines_match("[..]b", "c"));
    assert!(!lines_match("b", "c"));
    assert!(!lines_match("b", "cb"));
}

// Compares JSON object for approximate equality.
// You can use `[..]` wildcard in strings (useful for OS dependent things such as paths).
// Arrays are sorted before comparison.
fn find_mismatch<'a>(expected: &'a Json, actual: &'a Json) -> Option<(&'a Json, &'a Json)> {
    use rustc_serialize::json::Json::*;
    match (expected, actual) {
        (&I64(l), &I64(r)) if l == r => None,
        (&F64(l), &F64(r)) if l == r => None,
        (&U64(l), &U64(r)) if l == r => None,
        (&Boolean(l), &Boolean(r)) if l == r => None,
        (&String(ref l), &String(ref r)) if lines_match(l, r) => None,
        (&Array(ref l), &Array(ref r)) => {
            if l.len() != r.len() {
                return Some((expected, actual));
            }

            fn sorted(xs: &Vec<Json>) -> Vec<&Json> {
                let mut result = xs.iter().collect::<Vec<_>>();
                // `unwrap` should be safe because JSON spec does not allow NaNs
                result.sort_by(|x, y| x.partial_cmp(y).unwrap());
                result
            }

            sorted(l).iter().zip(sorted(r))
             .filter_map(|(l, r)| find_mismatch(l, r))
             .nth(0)
        }
        (&Object(ref l), &Object(ref r)) => {
            let same_keys = l.len() == r.len() && l.keys().all(|k| r.contains_key(k));
            if !same_keys {
                return Some((expected, actual));
            }

            l.values().zip(r.values())
             .filter_map(|(l, r)| find_mismatch(l, r))
             .nth(0)
        }
        (&Null, &Null) => None,
        _ => Some((expected, actual)),
    }

}

struct ZipAll<I1: Iterator, I2: Iterator> {
    first: I1,
    second: I2,
}

impl<T, I1: Iterator<Item=T>, I2: Iterator<Item=T>> Iterator for ZipAll<I1, I2> {
    type Item = (Option<T>, Option<T>);
    fn next(&mut self) -> Option<(Option<T>, Option<T>)> {
        let first = self.first.next();
        let second = self.second.next();

        match (first, second) {
            (None, None) => None,
            (a, b) => Some((a, b))
        }
    }
}

fn zip_all<T, I1: Iterator<Item=T>, I2: Iterator<Item=T>>(a: I1, b: I2) -> ZipAll<I1, I2> {
    ZipAll {
        first: a,
        second: b,
    }
}

impl fmt::Display for Execs {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "execs")
    }
}

impl ham::Matcher<ProcessBuilder> for Execs {
    fn matches(&self, mut process: ProcessBuilder) -> ham::MatchResult {
        self.matches(&mut process)
    }
}

impl<'a> ham::Matcher<&'a mut ProcessBuilder> for Execs {
    fn matches(&self, process: &'a mut ProcessBuilder) -> ham::MatchResult {
        println!("running {}", process);
        let res = process.exec_with_output();

        match res {
            Ok(out) => self.match_output(&out),
            Err(ProcessError { output: Some(ref out), .. }) => {
                self.match_output(out)
            }
            Err(e) => {
                let mut s = format!("could not exec process {}: {}", process, e);
                match e.cause() {
                    Some(cause) => s.push_str(&format!("\ncaused by: {}",
                                                       cause.description())),
                    None => {}
                }
                Err(s)
            }
        }
    }
}

impl ham::Matcher<Output> for Execs {
    fn matches(&self, output: Output) -> ham::MatchResult {
        self.match_output(&output)
    }
}

pub fn execs() -> Execs {
    Execs {
        expect_stdout: None,
        expect_stderr: None,
        expect_stdin: None,
        expect_exit_code: None,
        expect_stdout_contains: Vec::new(),
        expect_stderr_contains: Vec::new(),
        expect_json: None,
    }
}

#[derive(Clone)]
pub struct ShellWrites {
    expected: String
}

impl fmt::Display for ShellWrites {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "`{}` written to the shell", self.expected)
    }
}

impl<'a> ham::Matcher<&'a [u8]> for ShellWrites {
    fn matches(&self, actual: &[u8])
        -> ham::MatchResult
    {
        let actual = String::from_utf8_lossy(actual);
        let actual = actual.to_string();
        ham::expect(actual == self.expected, actual)
    }
}

pub fn shell_writes<T: fmt::Display>(string: T) -> ShellWrites {
    ShellWrites { expected: string.to_string() }
}

pub trait Tap {
    fn tap<F: FnOnce(&mut Self)>(self, callback: F) -> Self;
}

impl<T> Tap for T {
    fn tap<F: FnOnce(&mut Self)>(mut self, callback: F) -> T {
        callback(&mut self);
        self
    }
}

pub fn basic_bin_manifest(name: &str) -> String {
    format!(r#"
        [package]

        name = "{}"
        version = "0.5.0"
        authors = ["wycats@example.com"]

        [[bin]]

        name = "{}"
    "#, name, name)
}

pub fn basic_lib_manifest(name: &str) -> String {
    format!(r#"
        [package]

        name = "{}"
        version = "0.5.0"
        authors = ["wycats@example.com"]

        [lib]

        name = "{}"
    "#, name, name)
}

pub fn path2url(p: PathBuf) -> Url {
    Url::from_file_path(&*p).ok().unwrap()
}

fn substitute_macros(input: &str) -> String {
    let macros = [
        ("[RUNNING]",     "     Running"),
        ("[COMPILING]",   "   Compiling"),
        ("[CREATED]",     "     Created"),
        ("[FINISHED]",    "    Finished"),
        ("[ERROR]",       "error:"),
        ("[WARNING]",     "warning:"),
        ("[DOCUMENTING]", " Documenting"),
        ("[FRESH]",       "       Fresh"),
        ("[UPDATING]",    "    Updating"),
        ("[ADDING]",      "      Adding"),
        ("[REMOVING]",    "    Removing"),
        ("[DOCTEST]",     "   Doc-tests"),
        ("[PACKAGING]",   "   Packaging"),
        ("[DOWNLOADING]", " Downloading"),
        ("[UPLOADING]",   "   Uploading"),
        ("[VERIFYING]",   "   Verifying"),
        ("[ARCHIVING]",   "   Archiving"),
        ("[INSTALLING]",  "  Installing"),
        ("[REPLACING]",   "   Replacing"),
        ("[UNPACKING]",   "   Unpacking"),
        ("[EXE]", if cfg!(windows) {".exe"} else {""}),
        ("[/]", if cfg!(windows) {"\\"} else {"/"}),
    ];
    let mut result = input.to_owned();
    for &(pat, subst) in macros.iter() {
        result = result.replace(pat, subst)
    }
    return result;
}
