#!/usr/bin/env python

import logging
import tempfile
import os
import shutil
import subprocess
import sys
import tarfile

from webkitpy.benchmark_runner.utils import get_path_from_project_root, force_remove
from zipfile import ZipFile

if sys.version_info > (3, 0):
    from urllib.request import urlretrieve
else:
    from urllib import urlretrieve


_log = logging.getLogger(__name__)


class BenchmarkBuilder(object):
    def __init__(self, name, plan, driver):
        self._name = name
        self._plan = plan
        self._driver = driver

    def __enter__(self):
        self._web_root = tempfile.mkdtemp(dir="/tmp")
        self._dest = os.path.join(self._web_root, self._name)
        if 'local_copy' in self._plan:
            self._copy_benchmark_to_temp_dir(self._plan['local_copy'])
        elif 'remote_archive' in self._plan:
            self._fetch_remote_archive(self._plan['remote_archive'])
        elif 'svn_source' in self._plan:
            self._checkout_with_subversion(self._plan['svn_source'])
        else:
            raise Exception('The benchmark location was not specified')

        _log.info('Copied the benchmark into: %s' % self._dest)
        try:
            if 'create_script' in self._plan:
                self._run_create_script(self._plan['create_script'])
            patch_file_key = "{driver}_benchmark_patch".format(driver=self._driver)
            if patch_file_key in self._plan:
                self._apply_patch(self._plan[patch_file_key])
            return self._web_root
        except Exception:
            self._clean()
            raise

    def __exit__(self, exc_type, exc_value, traceback):
        self._clean()

    def _run_create_script(self, create_script):
        old_working_directory = os.getcwd()
        os.chdir(self._dest)
        _log.debug('Running %s in %s' % (create_script, self._dest))
        error_code = subprocess.call(create_script)
        os.chdir(old_working_directory)
        if error_code:
            raise Exception('Cannot create the benchmark - Error: %s' % error_code)

    def _copy_benchmark_to_temp_dir(self, benchmark_path):
        shutil.copytree(get_path_from_project_root(benchmark_path), self._dest)

    def _fetch_remote_archive(self, archive_url):
        if archive_url.endswith('.zip'):
            archive_type = 'zip'
        elif archive_url.endswith('tar.gz'):
            archive_type = 'tar.gz'
        else:
            raise Exception('Could not infer the file extention from URL: %s' % archive_url)

        archive_path = os.path.join(self._web_root, 'archive.' + archive_type)
        _log.info('Downloading %s to %s' % (archive_url, archive_path))
        urlretrieve(archive_url, archive_path)

        if archive_type == 'zip':
            with ZipFile(archive_path, 'r') as archive:
                archive.extractall(self._dest)
        elif archive_type == 'tar.gz':
            with tarfile.open(archive_path, 'r:gz') as archive:
                archive.extractall(self._dest)

        unarchived_files = [name for name in os.listdir(self._dest) if not name.startswith('.')]
        if len(unarchived_files) == 1:
            first_file = os.path.join(self._dest, unarchived_files[0])
            if os.path.isdir(first_file):
                shutil.move(first_file, self._web_root)
                os.rename(os.path.join(self._web_root, unarchived_files[0]), self._dest)

    def _checkout_with_subversion(self, subversion_url):
        _log.info('Checking out %s to %s' % (subversion_url, self._dest))
        error_code = subprocess.call(['svn', 'checkout', '--trust-server-cert', '--non-interactive', subversion_url, self._dest])
        if error_code:
            raise Exception('Cannot checkout the benchmark - Error: %s' % error_code)

    def _apply_patch(self, patch):
        old_working_directory = os.getcwd()
        os.chdir(self._dest)
        error_code = subprocess.call(['patch', '-p1', '-f', '-i', get_path_from_project_root(patch)])
        os.chdir(old_working_directory)
        if error_code:
            raise Exception('Cannot apply patch, will skip current benchmark_path - Error: %s' % error_code)

    def _clean(self):
        _log.info('Cleaning Benchmark')
        if self._web_root:
            force_remove(self._web_root)
