// Copyright 2018 Google LLC
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

// This build script is responsible for building BoringSSL with the appropriate
// symbol prefix. See boringssl/README.md for details.

use std::env;
use std::fs;
use std::process::{Command, Stdio};

// Relative to CARGO_MANIFEST_DIR
const BORINGSSL_SRC: &str = "boringssl/boringssl";

// Relative to OUT_DIR
const BUILD_DIR_1: &str = "boringssl/build_1";
const BUILD_DIR_2: &str = "boringssl/build_2";
const SYMBOL_FILE: &str = "boringssl/symbols.txt";

fn env(name: &str) -> String {
    let var = env::var(name).expect(&format!("missing required environment variable {}", name));
    println!("cargo:rerun-if-env-changed={}", var);
    var
}

fn main() {
    validate_dependencies();

    let manifest_dir = env("CARGO_MANIFEST_DIR");
    let abs_boringssl_src = format!("{}/{}", manifest_dir, BORINGSSL_SRC);

    let out_dir = env("OUT_DIR");
    let abs_build_dir_1 = format!("{}/{}", out_dir, BUILD_DIR_1);
    let abs_build_dir_2 = format!("{}/{}", out_dir, BUILD_DIR_2);
    let abs_symbol_file = format!("{}/{}", out_dir, SYMBOL_FILE);

    fs::create_dir_all(&abs_build_dir_1).expect("failed to create first build directory");
    fs::create_dir_all(&abs_build_dir_2).expect("failed to create second build directory");

    let major = env("CARGO_PKG_VERSION_MAJOR");
    let minor = env("CARGO_PKG_VERSION_MINOR");
    let patch = env("CARGO_PKG_VERSION_PATCH");
    let version_string = format!("{}_{}_{}", major, minor, patch);
    let prefix = format!("__RUST_MUNDANE_{}", version_string);
    let cmake_version_flag = format!("-DBORINGSSL_PREFIX={}", prefix);

    let built_with = built_with(&abs_build_dir_1);
    let have_ninja = have_ninja();
    let build = |build_dir, flags: &[&str]| {
        // Add CMAKE_POSITION_INDEPENDENT_CODE=1 to the list of CMake variables.
        // This causes compilation with -fPIC, which is required on some
        // platforms. This was added to address
        // https://github.com/google/mundane/issues/3
        let mut flags = flags.to_vec();
        flags.push("-DCMAKE_POSITION_INDEPENDENT_CODE=1");
        fn with_ninja<'a, 'b>(flags: &'a [&'b str]) -> Vec<&'b str> {
            let mut flags = flags.to_vec();
            flags.push("-GNinja");
            flags
        }

        env::set_current_dir(build_dir).expect("failed to cd to build directory");
        // If we've already run a build, then we need to build with the same
        // tool the second time around, or cmake will complain. There's
        // technically a chance that, after having built, the user uninstalled
        // the build tool, but that's unlikely enough that it's not worth
        // introducing the complexity necessary to support that use case.
        match built_with {
            Some(BuildSystem::Ninja) => {
                run("cmake", &with_ninja(&flags));
                run("ninja", &["crypto"]);
            }
            Some(BuildSystem::Make) => {
                run("cmake", &flags);
                run("make", &["crypto"]);
            }
            None => {
                if have_ninja {
                    run("cmake", &with_ninja(&flags));
                    run("ninja", &["crypto"]);
                } else {
                    run("cmake", &flags);
                    run("make", &["crypto"]);
                }
            }
        }
    };

    build(&abs_build_dir_1, &[&abs_boringssl_src]);

    // 'go run' requires that we're cd'd into a subdirectory of the Go module
    // root in order for Go modules to work
    let orig = env::current_dir().expect("could not get current directory");
    env::set_current_dir(&format!("{}/util", &abs_boringssl_src))
        .expect("could not set current directory");
    run(
        "go",
        &[
            "run",
            "read_symbols.go",
            "-out",
            &abs_symbol_file,
            &format!("{}/crypto/libcrypto.a", &abs_build_dir_1),
        ],
    );
    env::set_current_dir(orig).expect("could not set current directory");

    build(
        &abs_build_dir_2,
        &[&abs_boringssl_src, &cmake_version_flag, "-DBORINGSSL_PREFIX_SYMBOLS=../symbols.txt"],
    );

    // NOTE(joshlf): We symlink rather than renaming so that the BoringSSL build
    // system won't notice that libcrypto.a is gone and spuriously attempt to
    // rebuild.
    #[cfg(unix)]
    let res = std::os::unix::fs::symlink(
        format!("{}/crypto/libcrypto.a", abs_build_dir_2),
        format!("{}/crypto/libcrypto_{}.a", abs_build_dir_2, version_string),
    );
    #[cfg(windows)]
    let res = std::os::windows::fs::symlink_file(
        format!("{}/crypto/libcrypto.a", abs_build_dir_2),
        format!("{}/crypto/libcrypto_{}.a", abs_build_dir_2, version_string),
    );
    // If symlinking isn't available, we fall back to renaming.
    #[cfg(not(any(unix, windows)))]
    let res = fs::rename(
        format!("{}/crypto/libcrypto.a", abs_build_dir_2),
        format!("{}/crypto/libcrypto_{}.a", abs_build_dir_2, version_string),
    );

    if let Err(err) = res {
        // If the error is an AlreadyExists error, that just means we've already
        // compiled before. Renaming to an existing file works without error, so
        // it's OK that our panic message only mentions symlinking.
        if err.kind() != std::io::ErrorKind::AlreadyExists {
            panic!("could not symlink to libcrypto.a: {}", err)
        }
    }

    println!("cargo:rustc-link-search=native={}/crypto", abs_build_dir_2);
}

// Validates that dependencies which we invoke directly are present, or panics
// with an error message. Does not check for dependencies of BoringSSL's build
// system.
fn validate_dependencies() {
    let go = have_go();
    let cmake = have_cmake();
    let ninja = have_ninja();
    let make = have_make();

    if !go {
        panic!(
            "

Missing build dependency Go (1.11 or higher).

"
        );
    }
    if !cmake {
        panic!(
            "

Missing build dependency CMake.

"
        );
    }
    if cfg!(windows) && !ninja {
        panic!(
            "

Building on Windows requires the Ninja tool. See https://ninja-build.org/.

"
        );
    }
    if !make && !ninja {
        panic!(
            "

Building requires either Make or Ninja (https://ninja-build.org/).

"
        );
    }
}

// Runs a command and panic if it fails.
fn run(cmd: &str, args: &[&str]) {
    let output = Command::new(cmd)
        .args(args)
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .output()
        .expect(&format!("failed to invoke {}", cmd));
    if !output.status.success() {
        panic!("{} failed with status {}", cmd, output.status);
    }
}

// Is Go installed?
fn have_go() -> bool {
    have("go", &["version"])
}

// Is CMake installed?
fn have_cmake() -> bool {
    have("cmake", &["--version"])
}

// Is Ninja installed?
fn have_ninja() -> bool {
    have("ninja", &["--version"])
}

// Is Make installed?
fn have_make() -> bool {
    have("make", &["--version"])
}

// Checks whether a program is installed by running it.
//
// `have` checks whether `name` is installed by running it with the provided
// `args`. It must exist successfully.
fn have(name: &str, args: &[&str]) -> bool {
    Command::new(name).args(args).output().map(|output| output.status.success()).unwrap_or(false)
}

enum BuildSystem {
    Ninja,
    Make,
}

// Checks which build tool was used for the previous build.
fn built_with(abs_dir: &str) -> Option<BuildSystem> {
    let is_file = |file| {
        fs::metadata(format!("{}/{}", abs_dir, file)).map(|meta| meta.is_file()).unwrap_or(false)
    };
    if is_file("build.ninja") {
        Some(BuildSystem::Ninja)
    } else if is_file("Makefile") {
        Some(BuildSystem::Make)
    } else {
        None
    }
}
