#!/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
from webkitpy.common.memoized import memoized

REST_API_URL = 'https://q1tzqfy48e.execute-api.us-west-2.amazonaws.com/v2_2/'
REST_API_ARCHIVE_ENDPOINT = 'archives/'
REST_API_MINIFIED_ARCHIVE_ENDPOINT = 'minified-archives/'
REST_API_PLATFORM_ENDPOINT = 'platforms'
REST_API_MINIFIED_PLATFORM_ENDPOINT = 'minified-platforms'


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_archive_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_archive_url(options, LastEvaluatedKey=None):
    if options.full:
        base_url = urlparse.urljoin(REST_API_URL, REST_API_ARCHIVE_ENDPOINT)
    else:
        base_url = urlparse.urljoin(REST_API_URL, REST_API_MINIFIED_ARCHIVE_ENDPOINT)

    api_url = urlparse.urljoin(base_url, '-'.join([options.platform, options.architecture, options.configuration]))
    if LastEvaluatedKey:
        querystring = urllib2.quote(json.dumps(LastEvaluatedKey))
        api_url += '?ExclusiveStartKey=' + querystring
        
    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 get_platforms(endpoint):
    platform_url = urlparse.urljoin(REST_API_URL, endpoint)
    r = urllib2.urlopen(platform_url)
    data = json.load(r)
    platforms = []
    for platform in data.get('Items'):
        platforms.append(str(platform['identifier']['S']))
    
    return platforms
     
@memoized
def minified_platforms():
    return get_platforms(REST_API_MINIFIED_PLATFORM_ENDPOINT)
 
@memoized
def unminified_platforms():
    return get_platforms(REST_API_PLATFORM_ENDPOINT)
 
def is_supported_platform(options):
    platform = '-'.join([options.platform, options.architecture, options.configuration])    
    if options.full:
        return platform in unminified_platforms()
    return platform in minified_platforms()


def validate_options(options):
    if not is_supported_platform(options):
        print('Unsupported platform combination: [{}], exiting...'.format('-'.join([options.platform, options.architecture, options.configuration])))
        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 fetch_revision_list(options, LastEvaluatedKey=None):
    url = get_api_archive_url(options, LastEvaluatedKey)
    r = urllib2.urlopen(url)
    data = json.load(r)
    revision_list = get_sorted_revisions(data)

    if 'LastEvaluatedKey' in data['revisions']:
        LastEvaluatedKey = data['revisions']['LastEvaluatedKey']
        revision_list += fetch_revision_list(options, LastEvaluatedKey)
        
    return revision_list
    
def main(options):
    validate_options(options)
    revision_list = fetch_revision_list(options)
    
    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)
