#!/usr/bin/env python
# Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS.  All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.

import httplib2
import json
import subprocess
import zlib

from tracing.value import histogram
from tracing.value import histogram_set
from tracing.value.diagnostics import generic_set
from tracing.value.diagnostics import reserved_infos


def _GenerateOauthToken():
    args = ['luci-auth', 'token']
    p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    if p.wait() == 0:
        output = p.stdout.read()
        return output.strip()
    else:
        raise RuntimeError(
            'Error generating authentication token.\nStdout: %s\nStderr:%s' %
            (p.stdout.read(), p.stderr.read()))


def _SendHistogramSet(url, histograms, oauth_token):
    """Make a HTTP POST with the given JSON to the Performance Dashboard.

  Args:
    url: URL of Performance Dashboard instance, e.g.
        "https://chromeperf.appspot.com".
    histograms: a histogram set object that contains the data to be sent.
    oauth_token: An oauth token to use for authorization.
  """
    headers = {'Authorization': 'Bearer %s' % oauth_token}

    serialized = json.dumps(_ApplyHacks(histograms.AsDicts()), indent=4)

    if url.startswith('http://localhost'):
        # The catapult server turns off compression in developer mode.
        data = serialized
    else:
        data = zlib.compress(serialized)

    print 'Sending %d bytes to %s.' % (len(data), url + '/add_histograms')

    http = httplib2.Http()
    response, content = http.request(url + '/add_histograms',
                                     method='POST',
                                     body=data,
                                     headers=headers)
    return response, content


# TODO(https://crbug.com/1029452): HACKHACK
# Remove once we have doubles in the proto and handle -infinity correctly.
def _ApplyHacks(dicts):
    for d in dicts:
        if 'running' in d:

            def _NoInf(value):
                if value == float('inf'):
                    return histogram.JS_MAX_VALUE
                if value == float('-inf'):
                    return -histogram.JS_MAX_VALUE
                return value

            d['running'] = [_NoInf(value) for value in d['running']]

    return dicts


def _LoadHistogramSetFromProto(options):
    hs = histogram_set.HistogramSet()
    with options.input_results_file as f:
        hs.ImportProto(f.read())

    return hs


def _AddBuildInfo(histograms, options):
    common_diagnostics = {
        reserved_infos.MASTERS: options.perf_dashboard_machine_group,
        reserved_infos.BOTS: options.bot,
        reserved_infos.POINT_ID: options.commit_position,
        reserved_infos.BENCHMARKS: options.test_suite,
        reserved_infos.WEBRTC_REVISIONS: str(options.webrtc_git_hash),
        reserved_infos.BUILD_URLS: options.build_page_url,
    }

    for k, v in common_diagnostics.items():
        histograms.AddSharedDiagnosticToAllHistograms(
            k.name, generic_set.GenericSet([v]))


def _DumpOutput(histograms, output_file):
    with output_file:
        json.dump(_ApplyHacks(histograms.AsDicts()), output_file, indent=4)


def UploadToDashboard(options):
    histograms = _LoadHistogramSetFromProto(options)
    _AddBuildInfo(histograms, options)

    if options.output_json_file:
        _DumpOutput(histograms, options.output_json_file)

    oauth_token = _GenerateOauthToken()
    response, content = _SendHistogramSet(options.dashboard_url, histograms,
                                          oauth_token)

    if response.status == 200:
        print 'Received 200 from dashboard.'
        return 0
    else:
        print('Upload failed with %d: %s\n\n%s' %
              (response.status, response.reason, content))
        return 1
