#!/usr/bin/env python

from __future__ import division, print_function, unicode_literals

import argparse
import collections
import glob
import os
import platform
import subprocess
import sys

sys.path.append(os.path.join(os.path.dirname(__file__), "build", "lib", "scripts"))
try:
    import cfg
except ImportError:
    pass

str = type("")  # For Python2


def main():
    os.chdir(os.path.dirname(sys.argv[0]))
    progname = sys.argv[0]
    parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument("-m", "--mode", metavar="MODE",
                        type=str, choices="dbg dev opt".split(), default="opt",
                        help="set build configuration:\n"
                        "  - opt: compile for fast binaries (default)\n"
                        "  - dev: compile for fast builds\n"
                        "  - dbg: add debugging symbols")
    parser.add_argument("-o", "--target-os", metavar="OS",
                        type=str,
                        help="target os (default: host os)")
    args = parser.parse_args()

    check_submodules()
    check_host()
    check_target(args)

    with cfg.step("configure mode") as msg:
        msg(args.mode, color="green")
    cfg.gn(mode=args.mode,
           target_os=args.target_os)

    print("make(1) it so!")


def check_submodules():
    if not os.path.exists(os.path.join("build/lib", ".git")):
        print("The build submodule is missing. Run:")
        print("  $ git submodule update --init")
        sys.exit(1)


def check_host():
    with cfg.step("checking host os") as msg:
        if cfg.host_os() in ["mac", "linux"]:
            msg(cfg.host_os(), color="green")
        else:
            msg(cfg.host_os(), color="red")
            print("\nSorry! libsfz requires Mac OS X or Linux")
            sys.exit(1)


def check_target(args):
    with cfg.step("checking target os") as msg:
        if args.target_os is None:
            args.target_os = cfg.host_os()
        checker = {
            ("mac", "mac"): check_mac,
            ("linux", "linux"): check_linux_native,
            ("linux", "mac"): check_mac_on_linux,
        }.get((cfg.host_os(), args.target_os))
        if checker is None:
            msg(args.target_os, color="red")
            sys.exit(1)
        msg(args.target_os, color="green")
    checker(args)


def check_mac(args):
    with cfg.step("checking Mac OS X version") as msg:
        ver = platform.mac_ver()[0]
        ver = tuple(int(x) for x in ver.split(".")[:2])
        if ver < (10, 9):
            msg("%d.%d" % ver, color="red")
            print("\nSorry! libsfz requires Mac OS X 10.9+")
            sys.exit(1)
        msg("%d.%d" % ver, color="green")

    missing = collections.OrderedDict()
    if not (check_clang() and check_libcxx()):
        missing["xcode"] = (
                "* Xcode can be installed via the App Store:\n"
                "    https://itunes.apple.com/en/app/xcode/id497799835\n"
                "  After installing, open it and accept the license agreement\n")

    if missing:
        print("\nmissing dependencies: %s\n" % " ".join(missing.keys()))
        for step in missing.values():
            sys.stdout.write(step)
        if any("Homebrew" in v for v in missing.values()):
            print("* Homebrew can be installed like so:")
            print('    $ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"')
        sys.exit(1)


def check_linux_native(args):
    with cfg.step("checking Linux distro") as msg:
        distro = platform.linux_distribution()
        if distro[0] == "Ubuntu":
            msg(" ".join(distro), color="green")
        else:
            msg(" ".join(distro) + " (untested)", color="yellow")

    missing = collections.OrderedDict()
    if not check_clang("clang++"):
        missing["clang"] = "clang"

    if missing:
        print("\nmissing dependencies: %s" % " ".join(missing.keys()))
        if len(missing) == 1:
            print("\nOn Ubuntu, you can install it with:\n")
        else:
            print("\nOn Ubuntu, you can install them with:\n")
        print("    $ sudo apt-get install %s" % (" ".join(missing.values())))
        sys.exit(1)


def check_mac_on_linux(args):
    missing = collections.OrderedDict()
    if not (check_clang("x86_64-apple-darwin15-clang++") and
            check_libcxx("x86_64-apple-darwin15-clang++")):
        missing["osxcross"] = (
                "* OSXCross can be found here:\n"
                "    https://github.com/tpoechtrager/osxcross\n"
                "  Download and build it, and ensure target/bin is in your $PATH\n")

    if missing:
        print("\nmissing dependencies: %s\n" % " ".join(missing.keys()))
        for step in missing.values():
            sys.stdout.write(step)
        sys.exit(1)


def check_clang(executable=""):
    """Compile a basic C++11 binary."""
    executable = executable or "clang++"
    return cfg.check_bin(
            ("%s -x c++ -std=c++11 - -o /dev/null" % executable).split(),
            what="clang",
            input="int main() { return 1; }")


def check_libcxx(executable=""):
    """Compile a basic C++11, libc++ binary."""
    executable = executable or "clang++"
    return cfg.check_bin(
            ("%s -x c++ -std=c++11 -stdlib=libc++ - -o /dev/null" % executable).split(),
            what="libc++",
            input="#include <chrono>\n\nint main() { return std::chrono::seconds(1).count(); }")


if __name__ == "__main__":
    main()
