from __future__ import print_function
import os
import platform
import subprocess
import sys
import tempfile
import textwrap

from timing import monotonic_time_nanos
from tracing import Tracing
from buck_tool import BuckTool, which, check_output
from buck_tool import BuckToolException, RestartBuck
from buck_version import get_clean_buck_version, get_dirty_buck_version


JAVA_CLASSPATHS = [
    "build/abi_processor/classes",
    "build/classes",
    "build/dx_classes",
    "src",
    "third-party/java/android/sdklib.jar",
    "third-party/java/aopalliance/aopalliance.jar",
    "third-party/java/args4j/args4j-2.0.30.jar",
    "third-party/java/asm/asm-debug-all-5.0.3.jar",
    "third-party/java/astyanax/astyanax-cassandra-1.56.38.jar",
    "third-party/java/astyanax/astyanax-core-1.56.38.jar",
    "third-party/java/astyanax/astyanax-thrift-1.56.38.jar",
    "third-party/java/astyanax/cassandra-1.2.3.jar",
    "third-party/java/astyanax/cassandra-thrift-1.2.3.jar",
    "third-party/java/astyanax/high-scale-lib-1.1.2.jar",
    "third-party/java/closure-templates/soy-excluding-deps.jar",
    "third-party/java/commons-cli/commons-cli-1.1.jar",
    "third-party/java/commons-codec/commons-codec-1.2.jar",
    "third-party/java/commons-compress/commons-compress-1.8.1.jar",
    "third-party/java/commons-lang/commons-lang-2.6.jar",
    "third-party/java/dd-plist/dd-plist.jar",
    "third-party/java/ddmlib/ddmlib-22.5.3.jar",
    "third-party/java/eclipse/org.eclipse.core.contenttype_3.4.200.v20130326-1255.jar",
    "third-party/java/eclipse/org.eclipse.core.jobs_3.5.300.v20130429-1813.jar",
    "third-party/java/eclipse/org.eclipse.core.resources_3.8.101.v20130717-0806.jar",
    "third-party/java/eclipse/org.eclipse.core.runtime_3.9.100.v20131218-1515.jar",
    "third-party/java/eclipse/org.eclipse.equinox.common_3.6.200.v20130402-1505.jar",
    "third-party/java/eclipse/org.eclipse.equinox.preferences_3.5.100.v20130422-1538.jar",
    "third-party/java/eclipse/org.eclipse.jdt.core_3.9.2.v20140114-1555.jar",
    "third-party/java/eclipse/org.eclipse.osgi_3.9.1.v20140110-1610.jar",
    "third-party/java/gson/gson-2.2.4.jar",
    "third-party/java/guava/guava-18.0.jar",
    "third-party/java/guice/guice-3.0.jar",
    "third-party/java/guice/guice-assistedinject-3.0.jar",
    "third-party/java/guice/guice-multibindings-3.0.jar",
    "third-party/java/icu4j/icu4j-54.1.1.jar",
    "third-party/java/ini4j/ini4j-0.5.2.jar",
    "third-party/java/jackson/jackson-annotations-2.0.5.jar",
    "third-party/java/jackson/jackson-core-2.0.5.jar",
    "third-party/java/jackson/jackson-databind-2.0.5.jar",
    "third-party/java/jackson/jackson-datatype-jdk7-2.5.0.jar",
    "third-party/java/jetty/jetty-all-9.0.4.v20130625.jar",
    "third-party/java/jetty/servlet-api.jar",
    "third-party/java/joda-time/joda-time-2.2.jar",
    "third-party/java/jsr/javax.inject-1.jar",
    "third-party/java/jsr/jsr305.jar",
    "third-party/java/log4j/log4j-1.2.16.jar",
    "third-party/java/nailgun/nailgun-server-0.9.2-SNAPSHOT.jar",
    "third-party/java/slf4j/slf4j-api-1.7.2.jar",
    "third-party/java/slf4j/slf4j-log4j12-1.7.2.jar",
    "third-party/java/stringtemplate/ST-4.0.8.jar",
    "third-party/java/thrift/libthrift-0.7.0.jar",
    "third-party/java/xz-java-1.3/xz-1.3.jar",
]

RESOURCES = {
    "abi_processor_classes": "build/abi_processor/classes",
    "android_agent_path": "assets/android/agent.apk",
    "buck_client": "build/ng",
    "buck_server": "bin/buck",
    "dx": "third-party/java/dx-from-kitkat/etc/dx",
    "jacoco_agent_jar": "third-party/java/jacoco/jacocoagent.jar",
    "log4j_config_file": "config/log4j.properties",
    "logging_config_file": "config/logging.properties",
    "path_to_asm_jar": "third-party/java/asm/asm-debug-all-5.0.3.jar",
    "path_to_buck_py": "src/com/facebook/buck/parser/buck.py",
    "path_to_compile_asset_catalogs_build_phase_sh": (
        "src/com/facebook/buck/apple/compile_asset_catalogs_build_phase.sh"),
    "path_to_compile_asset_catalogs_py": (
        "src/com/facebook/buck/apple/compile_asset_catalogs.py"),
    "path_to_intellij_py": "src/com/facebook/buck/command/intellij.py",
    "path_to_pathlib_py": "third-party/py/pathlib/pathlib.py",
    "path_to_pex": "src/com/facebook/buck/python/pex.py",
    "path_to_python_test_main": "src/com/facebook/buck/python/__test_main__.py",
    "path_to_sh_binary_template": "src/com/facebook/buck/shell/sh_binary_template",
    "path_to_static_content": "webserver/static",
    "quickstart_origin_dir": "src/com/facebook/buck/cli/quickstart/android",
    "report_generator_jar": "build/report-generator.jar",
    "testrunner_classes": "build/testrunner/classes",
}


class BuckRepo(BuckTool):

    def __init__(self, buck_bin_dir, buck_project):
        super(BuckRepo, self).__init__(buck_project)

        self._buck_dir = self._platform_path(os.path.dirname(buck_bin_dir))
        self._build_success_file = os.path.join(
            self._buck_dir, "build", "successful-build")

        dot_git = os.path.join(self._buck_dir, '.git')
        self._is_git = os.path.exists(dot_git) and os.path.isdir(dot_git) and which('git') and \
            sys.platform != 'cygwin'
        self._is_buck_repo_dirty_override = os.environ.get('BUCK_REPOSITORY_DIRTY')

        buck_version = buck_project.buck_version
        if self._is_git and not buck_project.has_no_buck_check and buck_version:
            revision = buck_version[0]
            branch = buck_version[1] if len(buck_version) > 1 else None
            self._checkout_and_clean(revision, branch)

        self._build()

    def _checkout_and_clean(self, revision, branch):
        with Tracing('BuckRepo._checkout_and_clean'):
            if not self._revision_exists(revision):
                print(textwrap.dedent("""\
                    Required revision {0} is not
                    available in the local repository.
                    Buck is fetching updates from git. You can disable this by creating
                    a '.nobuckcheck' file in your repository, but this might lead to
                    strange bugs or build failures.""".format(revision)),
                      file=sys.stderr)
                git_command = ['git', 'fetch']
                git_command.extend(['--all'] if not branch else ['origin', branch])
                try:
                    subprocess.check_call(
                        git_command,
                        stdout=sys.stderr,
                        cwd=self._buck_dir)
                except subprocess.CalledProcessError:
                    raise BuckToolException(textwrap.dedent("""\
                          Failed to fetch Buck updates from git."""))

            current_revision = self._get_git_revision()

            if current_revision != revision:
                print(textwrap.dedent("""\
                    Buck is at {0}, but should be {1}.
                    Buck is updating itself. To disable this, add a '.nobuckcheck'
                    file to your project root. In general, you should only disable
                    this if you are developing Buck.""".format(
                    current_revision, revision)),
                    file=sys.stderr)

                try:
                    subprocess.check_call(
                        ['git', 'checkout', '--quiet', revision],
                        cwd=self._buck_dir)
                except subprocess.CalledProcessError:
                    raise BuckToolException(textwrap.dedent("""\
                          Failed to update Buck to revision {0}.""".format(revision)))
                if os.path.exists(self._build_success_file):
                    os.remove(self._build_success_file)

                ant = self._check_for_ant()
                self._run_ant_clean(ant)
                raise RestartBuck()

    def _join_buck_dir(self, relative_path):
        return os.path.join(self._buck_dir, *(relative_path.split('/')))

    def _is_dirty(self):
        if self._is_buck_repo_dirty_override:
            return self._is_buck_repo_dirty_override == "1"

        if not self._is_git:
            return False

        output = check_output(
            ['git', 'status', '--porcelain'],
            cwd=self._buck_dir)
        return bool(output.strip())

    def _has_local_changes(self):
        if not self._is_git:
            return False

        output = check_output(
            ['git', 'ls-files', '-m'],
            cwd=self._buck_dir)
        return bool(output.strip())

    def _get_git_revision(self):
        if not self._is_git:
            return 'N/A'

        output = check_output(
            ['git', 'rev-parse', 'HEAD', '--'],
            cwd=self._buck_dir)
        return output.splitlines()[0].strip()

    def _get_git_commit_timestamp(self):
        if self._is_buck_repo_dirty_override or not self._is_git:
            return -1

        return check_output(
            ['git', 'log', '--pretty=format:%ct', '-1', 'HEAD', '--'],
            cwd=self._buck_dir).strip()

    def _revision_exists(self, revision):
        returncode = subprocess.call(
            ['git', 'cat-file', '-e', revision],
            cwd=self._buck_dir)
        return returncode == 0

    def _check_for_ant(self):
        ant = which('ant')
        if not ant:
            message = "You do not have ant on your $PATH. Cannot build Buck."
            if sys.platform == "darwin":
                message += "\nTry running 'brew install ant'."
            raise BuckToolException(message)
        return ant

    def _print_ant_failure_and_exit(self, ant_log_path):
        print(textwrap.dedent("""\
                ::: 'ant' failed in the buck repo at '{0}',
                ::: and 'buck' is not properly built. It will be unusable
                ::: until the error is corrected. You can check the logs
                ::: at {1} to figure out what broke.""".format(
              self._buck_dir, ant_log_path)), file=sys.stderr)
        if self._is_git:
            raise BuckToolException(textwrap.dedent("""\
                ::: It is possible that running this command will fix it:
                ::: git -C "{0}" clean -xfd""".format(self._buck_dir)))
        else:
            raise BuckToolException(textwrap.dedent("""\
                ::: It is possible that running this command will fix it:
                ::: rm -rf "{0}"/build""".format(self._buck_dir)))

    def _run_ant_clean(self, ant):
        clean_log_path = os.path.join(self._buck_project.get_buck_out_log_dir(), 'ant-clean.log')
        with open(clean_log_path, 'w') as clean_log:
            exitcode = subprocess.call([ant, 'clean'], stdout=clean_log,
                                       cwd=self._buck_dir)
            if exitcode is not 0:
                self._print_ant_failure_and_exit(clean_log_path)

    def _run_ant(self, ant):
        ant_log_path = os.path.join(self._buck_project.get_buck_out_log_dir(), 'ant.log')
        with open(ant_log_path, 'w') as ant_log:
            exitcode = subprocess.call([ant], stdout=ant_log,
                                       cwd=self._buck_dir)
            if exitcode is not 0:
                self._print_ant_failure_and_exit(ant_log_path)

    def _build(self):
        with Tracing('BuckRepo._build'):
            if not os.path.exists(self._build_success_file):
                print(
                    "Buck does not appear to have been built -- building Buck!",
                    file=sys.stderr)
                ant = self._check_for_ant()
                self._run_ant_clean(ant)
                self._run_ant(ant)
                open(self._build_success_file, 'w').close()

    def _has_resource(self, resource):
        return True

    def _get_resource(self, resource, exe=False):
        return self._join_buck_dir(RESOURCES[resource.name])

    def _get_buck_version_uid(self):
        with Tracing('BuckRepo._get_buck_version_uid'):

            # First try to get the "clean" buck version.  If it succeeds,
            # return it.
            clean_version = get_clean_buck_version(
                self._buck_dir,
                allow_dirty=self._is_buck_repo_dirty_override == "1")
            if clean_version is not None:
                return clean_version

            # Otherwise, if there is a .nobuckcheck file, or if there isn't
            # a .buckversion file, fall back to a "dirty" version.
            if (self._buck_project.has_no_buck_check or
                    not self._buck_project.buck_version):
                return get_dirty_buck_version(self._buck_dir)

            if self._has_local_changes():
                print(textwrap.dedent("""\
                ::: Your buck directory has local modifications, and therefore
                ::: builds will not be able to use a distributed cache.
                ::: The following files must be either reverted or committed:"""),
                      file=sys.stderr)
                subprocess.call(
                    ['git', 'ls-files', '-m'],
                    stdout=sys.stderr,
                    cwd=self._buck_dir)
            elif os.environ.get('BUCK_CLEAN_REPO_IF_DIRTY') != 'NO':
                print(textwrap.dedent("""\
                ::: Your local buck directory is dirty, and therefore builds will
                ::: not be able to use a distributed cache."""), file=sys.stderr)
                if sys.stdout.isatty():
                    print(
                        "::: Do you want to clean your buck directory? [y/N]",
                        file=sys.stderr)
                    choice = raw_input().lower()
                    if choice == "y":
                        subprocess.call(
                            ['git', 'clean', '-fd'],
                            stdout=sys.stderr,
                            cwd=self._buck_dir)
                        raise RestartBuck()

            return get_dirty_buck_version(self._buck_dir)

    def _get_extra_java_args(self):
        return [
            "-Dbuck.git_commit={0}".format(self._get_git_revision()),
            "-Dbuck.git_commit_timestamp={0}".format(
                self._get_git_commit_timestamp()),
            "-Dbuck.git_dirty={0}".format(int(self._is_dirty())),
        ]

    def _get_bootstrap_classpath(self):
        return self._join_buck_dir("build/bootstrapper/classes")

    def _get_java_classpath(self):
        return self._pathsep.join([self._join_buck_dir(p) for p in JAVA_CLASSPATHS])
