#!/usr/bin/env python

# Copyright (C) 2017 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer. 
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution. 
# 3.  Neither the name of Apple Inc. ("Apple") nor the names of
#     its contributors may be used to endorse or promote products derived
#     from this software without specific prior written permission. 
#
# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import argparse
import bisect
import json
import math
import os
import shutil
import subprocess
import sys
import tempfile
import urllib2
import urlparse

REST_API_URL = 'https://q1tzqfy48e.execute-api.us-west-2.amazonaws.com/v2/'
REST_API_ENDPOINT = 'archives/'
REST_API_MINIFIED_ENDPOINT = 'minified-archives/'


def bisect_builds(revision_list, start_index, end_index, options):
    while True:
        index_to_test = pick_next_build(revision_list, start_index, end_index)
        if index_to_test == None:
            print('No more builds to test...')
            exit(1)
        download_archive(options, revision_list[index_to_test])
        extract_archive(options)
        reproduces = test_archive(options, revision_list[index_to_test])

        if reproduces:          # bisect left
            index_to_test -= 1  # We can remove this from the end of the list of builds to test
            bisect_builds(revision_list, start_index, index_to_test, options)
        if not reproduces:      # bisect right
            index_to_test += 1  # We can remove this from the start of the list of builds to test
            bisect_builds(revision_list, index_to_test, end_index, options)


def download_archive(options, revision):
    api_url = get_api_url(options)
    s3_url = get_s3_location_for_revision(api_url, revision)
    print('Archive URL: {}'.format(s3_url))
    command = ['python', '../BuildSlaveSupport/download-built-product', '--{}'.format(options.configuration), '--platform', options.platform, s3_url]
    print('Downloading revision: {}'.format(revision))
    subprocess.check_call(command)


def extract_archive(options):
    command = ['python', '../BuildSlaveSupport/built-product-archive', '--platform', options.platform, '--%s' % options.configuration, 'extract']
    subprocess.check_call(command)


# ---- bisect helpers from https://docs.python.org/2/library/bisect.html ----
def find_le(a, x):
    """Find rightmost value less than or equal to x"""
    i = bisect.bisect_right(a, x)
    if i:
        return i - 1
    raise ValueError


def find_ge(a, x):
    """Find leftmost item greater than or equal to x"""
    i = bisect.bisect_left(a, x)
    if i != len(a):
        return i
    raise ValueError
# ---- end bisect helpers ----


def get_api_url(options):
    if options.full:
        base_url = urlparse.urljoin(REST_API_URL, REST_API_ENDPOINT)
    else:
        base_url = urlparse.urljoin(REST_API_URL, REST_API_MINIFIED_ENDPOINT)

    api_url = urlparse.urljoin(base_url, '-'.join([options.platform, options.architecture, options.configuration]))
    return api_url


def get_indices_from_revisions(revision_list, start_revision, end_revision):
    if start_revision is None:
        print('WARNING: No starting revision was given, defaulting to first available for this configuration')
        start_index = 0
    else:
        start_index = find_ge(revision_list, start_revision)

    if end_revision is None:
        print('WARNING: No ending revision was given, defaulting to last avialable for this configuration')
        end_index = len(revision_list) - 1
    else:
        end_index = find_le(revision_list, end_revision)

    return start_index, end_index


def get_sorted_revisions(revisions_dict):
    revisions = [int(item['revision']['N']) for item in revisions_dict['revisions']['Items']]
    return sorted(revisions)
    

def get_s3_location_for_revision(url, revision):
    url = '/'.join([url, str(revision)])
    r = urllib2.urlopen(url)
    data = json.load(r)
    
    for archive in data['archive']:
        s3_url = archive['s3_url']
    return s3_url


def parse_args(args):
    helptext = 'bisect-builds is designed to help pinpoint regressions to specific code changes. It does this by bisecting across archives produced by build.webkit.org. Full and "minified" archives are available. Minified archives are significantly smaller, as they have been stripped of dSYMs and other non-essential components.'
    parser = argparse.ArgumentParser(description=helptext)
    parser.add_argument('-c', '--configuration', default='release', help='The configuration to query [release | debug]')
    parser.add_argument('-a', '--architecture', default='x86_64', help='The architecture to query [x86_64 | i386]')
    parser.add_argument('-p', '--platform', default='None', required=True, help='The platform to query [mac-sierra | gtk | ios-simulator | win]')
    parser.add_argument('-f', '--full', action='store_true', default=False, help='Use full archives containing debug symbols. These are significantly larger files!')
    parser.add_argument('-s', '--start', default=None, type=int, help='The starting revision to bisect.')
    parser.add_argument('-e', '--end', default=None, type=int, help='The ending revision to bisect')
    parser.add_argument('-l', '--list', action='store_true', default=False, help='Display a list of platforms and revisions')
    return parser.parse_args(args)


def pick_next_build(revision_list, start_index, end_index):
    revisions_remaining = (end_index - start_index) + 1
    print('Found {} revisions in this range to test...'.format(revisions_remaining))

    if start_index >= end_index:
        print('No archives available between {} and {}'.format(revision_list[end_index], revision_list[start_index]))
        return None

    middleIndex = (start_index + end_index) / 2
    return int(math.ceil(middleIndex))


def prompt_did_reproduce():
    var = raw_input('\nDid the error reproduce? [y/n]: ')
    var = var.lower()
    if 'y' in var:
        return True
    if 'n' in var:
        return False
    else:
        prompt_did_reproduce()
    

def set_webkit_output_dir(temp_dir):
    print('Setting environment variable WEBKIT_OUTPUTDIR to {}'.format(temp_dir))
    os.environ['WEBKIT_OUTPUTDIR'] = temp_dir


def test_archive(options, revision):
    print('Testing revision {}...'.format(revision))
    command = []
    if 'mac' in options.platform:
        command = ['./run-safari']
    elif 'ios' in options.platform:
        command = ['./run-safari', '--simulator']
    else:
        print('Default test behavior for this platform is not implemented...'.format(options.platform))

    if command:
        subprocess.call(command)
    return prompt_did_reproduce()
    

def minified_platforms():
    # FIXME: query this dynamically from API
    return  ['mac-elcapitan', 'mac-sierra', 'mac-highsierra', 'ios-simulator-10', 'ios-simulator-11']


def unminified_platforms():
    # FIXME: query this dynamically from API
    return ['gtk', 'ios-simulator-10', 'ios-simulator-11', 'mac-elcapitan', 'mac-sierra', 'mac-highsierra', 'win', 'wpe']


def is_supported_platform(options):
    if options.full:
        return options.platform in unminified_platforms()
    return options.platform in minified_platforms()


def validate_options(options):
    if not is_supported_platform(options):
        print('Unsupported platform: [{}], exiting...'.format(options.platform))
        if options.full:
            print('Available Unminified platforms: {}'.format(unminified_platforms()))
        else:
            print('Available Minified platforms: {}'.format(minified_platforms()))
            print('INFO: pass --full to try against full archives')
        exit(1)

def print_list_and_exit(revision_list, options):
        print('Supported minified platforms: {}'.format(minified_platforms()))
        print('Supported unminified platforms: {}'.format(unminified_platforms()))
        print('{} revisions available for supplied platform: {}-{}-{}:'.format(len(revision_list), options.platform, options.architecture, options.configuration))
        print(revision_list)
        exit(0)

def main(options):
    validate_options(options)

    url = get_api_url(options)
    r = urllib2.urlopen(url)
    data = json.load(r)
    
    revision_list = get_sorted_revisions(data)

    if options.list:
        print_list_and_exit(revision_list, options)

    start_index, end_index = get_indices_from_revisions(revision_list, options.start, options.end)
    print('Bisecting between {} and {}'.format(revision_list[start_index], revision_list[end_index]))
    
    # from here forward, use indices instead of revisions
    bisect_builds(revision_list, start_index, end_index, options)


if __name__ == '__main__':
    options = parse_args(sys.argv[1:])
    script_path = os.path.abspath(__file__)
    script_directory = os.path.dirname(script_path)
    os.chdir(script_directory)
    webkit_output_dir = tempfile.mkdtemp()
    set_webkit_output_dir(webkit_output_dir)
    try:
        main(options)    
    except KeyboardInterrupt:
        exit("Aborting.")
    finally:
        shutil.rmtree(webkit_output_dir, ignore_errors=True)
