#!/usr/bin/env python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from skypy.find_tests import find_tests
from skypy.paths import Paths
import argparse
import os
import re
import requests
import skypy.configuration as configuration
import skypy.skyserver
import subprocess


SUPPORTED_MIME_TYPES = [
    'text/sky',
    'application/dart',
]
HTTP_PORT = 9999
URL_ROOT = 'http://localhost:%s/' % HTTP_PORT
DASHBOARD_URL = 'https://chromeperf.appspot.com/add_point'
BENCHMARKS_DIR = 'benchmarks'


def values_from_output(output):
    # Parse out the raw values from the PerfRunner output:
    #   values 90, 89, 93 ms
    # We'll probably need a fancier parser at some point.
    match = re.search(r'values (.+) ms', output, flags=re.MULTILINE)
    return map(float, match.group(1).split(', '))


def create_json_blob(values):
    revision = subprocess.check_output(["git", "show-ref", "HEAD", "-s"]).strip()
    return {
        "master": "master.mojo.perf",
        "bot": "sky-release",
        "point_id": 123456, # FIXME: We need to generate a monotonicly increasing number somehow.
        "versions": {
          "mojo": revision
        },
        "chart_data": {
            "format_version": "1.0",
            "benchmark_name": "layout.simple-blocks",
            "charts": {
                "warm_times": {
                    "traces": {
                        "layout.simple-blocks": {
                            "type": "list_of_scalar_values",
                            "values": values,
                        },
                    }
                }
            }
        }
    }


def send_json_to_dashboard(json):
    requests.post(DASHBOARD_URL, params={ 'data': json })


class PerfHarness(object):
    def __init__(self, args):
        self._sky_server = None
        self.paths = Paths(os.path.join('out', 'Debug'))
        self.args = args

    def _start_server(self):
        # TODO(eseidel): Shouldn't this just use skyserver.py?
        return subprocess.Popen([
            SkyServer.sky_server_path(),
            self.paths.src_root,
            str(HTTP_PORT),
            '-t', self.args.configuration
        ])

    def _sky_tester_command(self, url):
        content_handlers = ['%s,%s' % (mime_type, 'mojo:sky_viewer')
            for mime_type in SUPPORTED_MIME_TYPES]
        return [
            self.paths.mojo_shell_path,
            '--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa',
            '--args-for=mojo:window_manager %s' % url,
            '--content-handlers=%s' % ','.join(content_handlers),
            '--url-mappings=mojo:window_manager=mojo:sky_tester',
            'mojo:window_manager',
        ]

    def _url_for_path(self, path):
        return URL_ROOT + os.path.relpath(path, self.paths.src_root)

    def _run_tests(self, path):
        url = self._url_for_path(path)
        output = subprocess.check_output(
            self._sky_tester_command(url),
            stderr=subprocess.STDOUT)
        values = values_from_output(output)
        print os.path.basename(path), "=>", values
        # FIXME: Upload JSON blob to results server:
        # json = create_json_blob(values)
        # send_json_to_dashboard(json)

    def main(self):
        self._start_server()
        map(self._run_tests, find_tests(os.path.join(self.paths.sky_root, BENCHMARKS_DIR)))

    def shutdown(self):
        if self._sky_server:
            self._sky_server.terminate()


def main():
    parser = argparse.ArgumentParser(description='Sky performance tester')
    configuration.add_arguments(parser)
    args = parser.parse_args()

    harness = PerfHarness(args)
    try:
        harness.main()
    except (KeyboardInterrupt, SystemExit):
        pass
    finally:
        harness.shutdown()


if __name__ == '__main__':
    main()
