extern crate data_encoding;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json as json;
extern crate tempdir;
extern crate tuf;

use data_encoding::HEXLOWER;
use std::fs::{self, File, DirBuilder};
use std::io::Read;
use std::path::PathBuf;
use tempdir::TempDir;
use tuf::{Tuf, Config, Error};
use tuf::meta::{Key, KeyValue, KeyType};
use tuf::util;


fn load_vector_meta() -> String {
    let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
        .join("tests")
        .join("tuf-test-vectors")
        .join("tuf")
        .join("vector-meta.json");
    let mut file = File::open(path).expect("couldn't open vector meta");
    let mut buf = String::new();
    file.read_to_string(&mut buf).expect("couldn't read vector meta");
    buf
}

#[derive(Deserialize)]
struct VectorMeta {
    vectors: Vec<VectorMetaEntry>,
}

#[derive(Deserialize)]
struct VectorMetaEntry {
    repo: String,
    error: Option<String>,
    root_keys: Vec<RootKeyData>,
}

#[derive(Deserialize)]
struct RootKeyData {
    path: String,
    #[serde(rename = "type")]
    typ: String,
}

fn run_test_vector(test_path: &str) {
    let temp_dir = TempDir::new("rust-tuf").expect("couldn't make temp dir");
    let temp_path = temp_dir.into_path();

    println!("Temp dir is: {:?}", temp_path);

    let vector_meta: VectorMeta = json::from_str(&load_vector_meta())
        .expect("couldn't deserializd meta");

    let test_vector = vector_meta.vectors.iter()
        .filter(|v| v.repo == test_path)
        .collect::<Vec<&VectorMetaEntry>>()
        .pop()
        .expect(format!("No repo named {}", test_path).as_str());

    let vector_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
        .join("tests")
        .join("tuf-test-vectors")
        .join("tuf")
        .join(test_vector.repo.clone());

    println!("The test vector path is: {}",
             vector_path.to_string_lossy().into_owned());

    let root_keys = test_vector.root_keys
        .iter()
        .map(|k| {
            let file_path = vector_path.join("keys").join(k.path.clone());
            let mut file = File::open(file_path).expect("couldn't open file");
            let mut key = String::new();
            file.read_to_string(&mut key).expect("couldn't read key");

            match k.typ.as_ref() {
                "ed25519" => {
                    let val = HEXLOWER.decode(key.replace("\n", "").as_ref())
                        .expect("key value not hex");
                    Key {
                        typ: KeyType::Ed25519,
                        value: KeyValue(val),
                    }
                }
                x => panic!("unknown key type: {}", x),
            }
        })
        .collect();

    let config = Config::build()
        .url(util::path_to_url(&vector_path.join("repo")).expect("couldn't make url"))
        .local_path(temp_path.clone())
        .finish()
        .expect("bad config");

    match (Tuf::from_root_keys(root_keys, config), &test_vector.error) {
        (Ok(ref tuf), &None) => {
            assert_eq!(tuf.list_targets(), vec!["targets/file.txt".to_string()]);
            // first time pulls remote
            assert_eq!(tuf.fetch_target("targets/file.txt").map(|_| ()), Ok(()));
            assert!(temp_path.join("targets").join("targets").join("file.txt").exists());
            // second time pulls local
            assert_eq!(tuf.fetch_target("targets/file.txt").map(|_| ()), Ok(()));
        }

        (Ok(ref tuf), &Some(ref err)) if err == &"TargetHashMismatch".to_string() => {
            assert_eq!(tuf.fetch_target("targets/file.txt").map(|_| ()),
                       Err(Error::TargetHashMismatch));
        }

        (Ok(ref tuf), &Some(ref err)) if err == &"OversizedTarget".to_string() => {
            assert_eq!(tuf.fetch_target("targets/file.txt").map(|_| ()),
                       Err(Error::OversizedTarget));
        }

        (Err(Error::ExpiredMetadata(ref role)), &Some(ref err))
            if err.starts_with("ExpiredMetadata::") => {
            assert!(err.to_lowercase()
                        .ends_with(role.to_string().as_str()),
                    format!("Role: {}, err: {}", role, err))
        }

        (Err(Error::UnmetThreshold(ref role)), &Some(ref err))
            if err.starts_with("UnmetThreshold::") => {
            assert!(err.to_lowercase()
                        .ends_with(role.to_string().as_str()),
                    format!("Role: {}, err: {}", role, err))
        }

        (Err(Error::MetadataHashMismatch(ref role)), &Some(ref err))
            if err.starts_with("MetadataHashMismatch::") => {
            assert!(err.to_lowercase()
                        .ends_with(role.to_string().as_str()),
                    format!("Role: {}, err: {}", role, err))
        }

        (Err(Error::OversizedMetadata(ref role)), &Some(ref err))
            if err.starts_with("OversizedMetadata::") => {
            assert!(err.to_lowercase()
                        .ends_with(role.to_string().as_str()),
                    format!("Role: {}, err: {}", role, err))
        }

        // we're using a json error because the threshold is checked in the deserializer
        // this may need to change in the future
        (Err(Error::Json(ref msg)), &Some(ref err)) if err.starts_with("IllegalThreshold::") => {
            let role = err.split("::").last().unwrap();

            assert!(msg.contains("threshold"),
                    format!("Role: {}, err: {}", role, err));
            assert!(err.to_lowercase()
                        .contains(role.to_lowercase().as_str()),
                    format!("Role: {}, err: {}", role, err))
        }

        x => panic!("Unexpected failures: {:?}", x),
    }
}

#[test]
fn vector_001() {
    run_test_vector("001")
}

#[test]
fn vector_002() {
    run_test_vector("002")
}

#[ignore]
fn vector_003() {
    run_test_vector("003")
}

#[ignore]
fn vector_004() {
    run_test_vector("004")
}

#[test]
fn vector_005() {
    run_test_vector("005")
}

#[ignore]
fn vector_006() {
    run_test_vector("006")
}

#[test]
fn vector_007() {
    run_test_vector("007")
}

#[test]
fn vector_008() {
    run_test_vector("008")
}

#[test]
fn vector_009() {
    run_test_vector("009")
}

#[test]
fn vector_010() {
    run_test_vector("010")
}

#[test]
fn vector_011() {
    run_test_vector("011")
}

#[test]
fn vector_012() {
    run_test_vector("012")
}

#[test]
fn vector_013() {
    run_test_vector("013")
}

#[test]
fn vector_014() {
    run_test_vector("014")
}

#[test]
fn vector_015() {
    run_test_vector("015")
}

#[test]
fn vector_016() {
    run_test_vector("016")
}

#[test]
fn vector_017() {
    run_test_vector("017")
}

#[test]
fn vector_018() {
    run_test_vector("018")
}

#[test]
fn vector_019() {
    run_test_vector("019")
}

#[test]
fn vector_020() {
    run_test_vector("020")
}

#[test]
fn vector_021() {
    run_test_vector("021")
}

#[test]
fn vector_022() {
    run_test_vector("022")
}

#[test]
fn vector_023() {
    run_test_vector("023")
}

#[test]
fn vector_024() {
    run_test_vector("024")
}

#[test]
fn vector_025() {
    run_test_vector("025")
}

#[test]
fn vector_026() {
    run_test_vector("026")
}

#[ignore]
fn vector_027() {
    run_test_vector("027")
}

#[ignore]
fn vector_028() {
    run_test_vector("028")
}

#[test]
fn vector_029() {
    run_test_vector("029")
}

#[test]
fn vector_030() {
    run_test_vector("030")
}

#[test]
fn vector_031() {
    run_test_vector("031")
}

#[test]
fn vector_032() {
    run_test_vector("032")
}

#[test]
fn vector_033() {
    run_test_vector("033")
}

#[test]
fn vector_034() {
    run_test_vector("034")
}
