# Copyright (C) 2013 Google 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:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * 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.
#     * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
# OWNER OR 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 json
import optparse

from blinkpy.web_tests.layout_package.json_results_generator import convert_times_trie_to_flat_paths
from blinkpy.web_tests.port.base import Port


def main(host, argv):
    parser = optparse.OptionParser(usage='%prog [times_ms.json]')
    parser.add_option('-f', '--forward', action='store', type='int',
                      help='group times by first N directories of test')
    parser.add_option('-b', '--backward', action='store', type='int',
                      help='group times by last N directories of test')
    parser.add_option('--fastest', action='store', type='float',
                      help='print a list of tests that will take N % of the time')

    epilog = """
       You can print out aggregate times per directory using the -f and -b
       flags. The value passed to each flag indicates the "depth" of the flag,
       similar to positive and negative arguments to python arrays.

       For example, given fast/forms/week/week-input-type.html, -f 1
       truncates to 'fast', -f 2 and -b 2 truncates to 'fast/forms', and -b 1
       truncates to fast/forms/week . -f 0 truncates to '', which can be used
       to produce a single total time for the run."""
    parser.epilog = '\n'.join(s.lstrip() for s in epilog.splitlines())

    options, args = parser.parse_args(argv)

    port = host.port_factory.get()
    if args and args[0]:
        times_ms_path = args[0]
    else:
        times_ms_path = host.filesystem.join(port.results_directory(), 'times_ms.json')

    times_trie = json.loads(host.filesystem.read_text_file(times_ms_path))

    times = convert_times_trie_to_flat_paths(times_trie)

    if options.fastest:
        if options.forward is None and options.backward is None:
            options.forward = 0
        print_fastest(host, port, options, times)
    else:
        print_times(host, options, times)


def print_times(host, options, times):
    by_key = times_by_key(times, options.forward, options.backward)
    for key in sorted(by_key):
        if key:
            host.print_('%s %d' % (key, by_key[key]))
        else:
            host.print_('%d' % by_key[key])


def print_fastest(host, port, options, times):
    total = times_by_key(times, 0, None)['']
    by_key = times_by_key(times, options.forward, options.backward)
    keys_by_time = sorted(by_key, key=lambda k: (by_key[k], k))

    tests_by_key = {}
    for test_name in sorted(times):
        key = key_for(test_name, options.forward, options.backward)
        if key in sorted(tests_by_key):
            tests_by_key[key].append(test_name)
        else:
            tests_by_key[key] = [test_name]

    fast_tests_by_key = {}
    total_so_far = 0
    per_key = total * options.fastest / (len(keys_by_time) * 100.0)
    budget = 0
    while keys_by_time:
        budget += per_key
        key = keys_by_time.pop(0)
        tests_by_time = sorted(tests_by_key[key], key=lambda t: (times[t], t))
        fast_tests_by_key[key] = []
        while tests_by_time and total_so_far <= budget:
            test = tests_by_time.pop(0)
            test_time = times[test]
            # Make sure test time > 0 so we don't include tests that are skipped.
            if test_time and total_so_far + test_time <= budget:
                fast_tests_by_key[key].append(test)
                total_so_far += test_time

    for k in sorted(fast_tests_by_key):
        for t in fast_tests_by_key[k]:
            host.print_('%s %d' % (t, times[t]))
    return


def key_for(path, forward, backward):
    sep = Port.TEST_PATH_SEPARATOR
    if forward is not None:
        return sep.join(path.split(sep)[:-1][:forward])
    if backward is not None:
        return sep.join(path.split(sep)[:-backward])
    return path


def times_by_key(times, forward, backward):
    by_key = {}
    for test_name in times:
        key = key_for(test_name, forward, backward)
        if key in by_key:
            by_key[key] += times[test_name]
        else:
            by_key[key] = times[test_name]
    return by_key
