//! Helper script to publish the wasm-bindgen suite of crates
//!
//! Usage:
//!
//! * First, compile this script
//! * Next, set cwd to the root of the wasm-bindgen repository
//! * Execute `./publish bump` to bump versions
//! * Send a PR
//! * Merge when green
//! * Execute `./publish publish` to publish crates

use std::collections::HashMap;
use std::env;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use std::process::Command;

// note that this list must be topologically sorted by dependencies
const CRATES_TO_PUBLISH: &[&str] = &[
    "wasm-bindgen-shared",
    "wasm-bindgen-backend",
    "wasm-bindgen-macro-support",
    "wasm-bindgen-macro",
    "wasm-bindgen-test-macro",
    "wasm-bindgen-test",
    "wasm-bindgen-wasm-interpreter",
    "wasm-bindgen-webidl",
    "wasm-bindgen-wasm-conventions",
    "wasm-bindgen-threads-xform",
    "wasm-bindgen-multi-value-xform",
    "wasm-bindgen-anyref-xform",
    "wasm-bindgen-cli-support",
    "wasm-bindgen-cli",
    "wasm-bindgen",
    "wasm-bindgen-futures",
    "js-sys",
    "web-sys",
];

const CRATES_TO_AVOID_PUBLISH: &[&str] = &[
    // We'll publish these when they're ready one day
    "wasm-bindgen-typescript",
    // These are internal crates, unlikely to ever be published
    "ui-tests",
    "sample",
    "webidl-tests",
    "typescript-tests",
];

struct Crate {
    manifest: PathBuf,
    name: String,
    version: String,
    next_version: String,
}

fn main() {
    let mut crates = Vec::new();
    crates.push(read_crate("./Cargo.toml".as_ref()));
    find_crates("crates".as_ref(), &mut crates);
    find_crates("examples".as_ref(), &mut crates);

    let pos = CRATES_TO_PUBLISH
        .iter()
        .chain(CRATES_TO_AVOID_PUBLISH)
        .enumerate()
        .map(|(i, c)| (*c, i))
        .collect::<HashMap<_, _>>();
    crates.sort_by_key(|krate| pos.get(&krate.name[..]));

    match &env::args().nth(1).expect("must have one argument")[..] {
        "bump" => {
            for krate in crates.iter() {
                bump_version(&krate, &crates);
            }
        }

        "publish" => {
            for krate in crates.iter() {
                publish(&krate);
            }
        }

        s => panic!("unknown command: {}", s),
    }
}

fn find_crates(dir: &Path, dst: &mut Vec<Crate>) {
    if dir.join("Cargo.toml").exists() {
        let krate = read_crate(&dir.join("Cargo.toml"));
        if CRATES_TO_PUBLISH
            .iter()
            .chain(CRATES_TO_AVOID_PUBLISH)
            .any(|c| krate.name == *c)
        {
            dst.push(krate);
        } else if dir.iter().any(|s| s == "examples") {
            dst.push(krate);
        } else {
            panic!("failed to find {:?} in whitelist or blacklist", krate.name);
        }
    }

    for entry in dir.read_dir().unwrap() {
        let entry = entry.unwrap();
        if entry.file_type().unwrap().is_dir() {
            find_crates(&entry.path(), dst);
        }
    }
}

fn read_crate(manifest: &Path) -> Crate {
    let mut name = None;
    let mut version = None;
    for line in fs::read_to_string(manifest).unwrap().lines() {
        if name.is_none() && line.starts_with("name = \"") {
            name = Some(
                line.replace("name = \"", "")
                    .replace("\"", "")
                    .trim()
                    .to_string(),
            );
        }
        if version.is_none() && line.starts_with("version = \"") {
            version = Some(
                line.replace("version = \"", "")
                    .replace("\"", "")
                    .trim()
                    .to_string(),
            );
        }
    }
    let name = name.unwrap();
    let version = version.unwrap();
    let next_version = if CRATES_TO_PUBLISH.contains(&&name[..]) {
        bump(&version)
    } else {
        version.clone()
    };
    Crate {
        manifest: manifest.to_path_buf(),
        name,
        version,
        next_version,
    }
}

fn bump_version(krate: &Crate, crates: &[Crate]) {
    let contents = fs::read_to_string(&krate.manifest).unwrap();

    let mut new_manifest = String::new();
    let mut is_deps = false;
    for line in contents.lines() {
        let mut rewritten = false;
        if line.starts_with("version =") {
            if CRATES_TO_PUBLISH.contains(&&krate.name[..]) {
                println!(
                    "bump `{}` {} => {}",
                    krate.name, krate.version, krate.next_version
                );
                new_manifest.push_str(&line.replace(&krate.version, &krate.next_version));
                rewritten = true;
            }
        }

        is_deps = if line.starts_with("[") {
            line.contains("dependencies")
        } else {
            is_deps
        };

        for other in crates {
            if !is_deps || !line.starts_with(&format!("{} ", other.name)) {
                continue;
            }
            if !line.contains(&other.version) {
                if !line.contains("version =") {
                    continue;
                }
                panic!(
                    "{:?} has a dep on {} but doesn't list version {}",
                    krate.manifest, other.name, other.version
                );
            }
            rewritten = true;
            new_manifest.push_str(&line.replace(&other.version, &other.next_version));
            break;
        }
        if !rewritten {
            new_manifest.push_str(line);
        }
        new_manifest.push_str("\n");
    }
    fs::write(&krate.manifest, new_manifest).unwrap();
}

fn bump(version: &str) -> String {
    let mut iter = version.split('.').map(|s| s.parse::<u32>().unwrap());
    let major = iter.next().expect("major version");
    let minor = iter.next().expect("minor version");
    let patch = iter.next().expect("patch version");
    format!("{}.{}.{}", major, minor, patch + 1)
}

fn publish(krate: &Crate) {
    if !CRATES_TO_PUBLISH.iter().any(|s| *s == krate.name) {
        return;
    }
    let status = Command::new("cargo")
        .arg("publish")
        .current_dir(krate.manifest.parent().unwrap())
        .arg("--no-verify")
        .arg("--allow-dirty")
        .status()
        .expect("failed to run cargo");
    if !status.success() {
        println!("FAIL: failed to publish `{}`: {}", krate.name, status);
    }
}
