#!/usr/bin/env python3
# Copyright 2018 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.
"""
This is script to upload ninja_log from googler.

Server side implementation is in
https://cs.chromium.org/chromium/infra/go/src/infra/appengine/chromium_build_stats/

Uploaded ninjalog is stored in BigQuery table having following schema.
https://cs.chromium.org/chromium/infra/go/src/infra/appengine/chromium_build_stats/ninjaproto/ninjalog.proto

The log will be used to analyze user side build performance.
"""

import argparse
import gzip
import io
import json
import logging
import multiprocessing
import os
import platform
import subprocess
import sys
import time

from third_party.six.moves.urllib import error
from third_party.six.moves.urllib import request

# These build configs affect build performance a lot.
# TODO(https://crbug.com/900161): Add 'blink_symbol_level' and
# 'enable_js_type_check'.
WHITELISTED_CONFIGS = ('symbol_level', 'use_goma', 'is_debug',
                       'is_component_build', 'enable_nacl', 'host_os',
                       'host_cpu', 'target_os', 'target_cpu')


def IsGoogler(server):
  """Check whether this script run inside corp network."""
  try:
    resp = request.urlopen('https://' + server + '/should-upload')
    return resp.read() == b'Success'
  except error.URLError:
    return False


def ParseGNArgs(gn_args):
  """Parse gn_args as json and return config dictionary."""
  configs = json.loads(gn_args)
  build_configs = {}

  for config in configs:
    key = config["name"]
    if key not in WHITELISTED_CONFIGS:
      continue
    if 'current' in config:
      build_configs[key] = config['current']['value']
    else:
      build_configs[key] = config['default']['value']

  return build_configs


def GetBuildTargetFromCommandLine(cmdline):
  """Get build targets from commandline."""

  # Skip argv0.
  idx = 1

  # Skipping all args that involve these flags, and taking all remaining args
  # as targets.
  onearg_flags = ('-C', '-f', '-j', '-k', '-l', '-d', '-t', '-w')
  zeroarg_flags = ('--version', '-n', '-v')

  targets = []

  while idx < len(cmdline):
    if cmdline[idx] in onearg_flags:
      idx += 2
      continue

    if (cmdline[idx][:2] in onearg_flags or cmdline[idx] in zeroarg_flags):
      idx += 1
      continue

    targets.append(cmdline[idx])
    idx += 1

  return targets


def GetJflag(cmdline):
  """Parse cmdline to get flag value for -j"""

  for i in range(len(cmdline)):
    if (cmdline[i] == '-j' and i + 1 < len(cmdline)
        and cmdline[i + 1].isdigit()):
      return int(cmdline[i + 1])

    if (cmdline[i].startswith('-j') and cmdline[i][len('-j'):].isdigit()):
      return int(cmdline[i][len('-j'):])


def GetMetadata(cmdline, ninjalog):
  """Get metadata for uploaded ninjalog.

    Returned metadata has schema defined in
    https://cs.chromium.org?q="type+Metadata+struct+%7B"+file:%5Einfra/go/src/infra/appengine/chromium_build_stats/ninjalog/

    TODO(tikuta): Collect GOMA_* env var.
    """

  build_dir = os.path.dirname(ninjalog)

  build_configs = {}

  try:
    args = ['gn', 'args', build_dir, '--list', '--short', '--json']
    if sys.platform == 'win32':
      # gn in PATH is bat file in windows environment (except cygwin).
      args = ['cmd', '/c'] + args

    gn_args = subprocess.check_output(args)
    build_configs = ParseGNArgs(gn_args)
  except subprocess.CalledProcessError as e:
    logging.error("Failed to call gn %s", e)
    build_configs = {}

  # Stringify config.
  for k in build_configs:
    build_configs[k] = str(build_configs[k])

  metadata = {
      'platform': platform.system(),
      'cpu_core': multiprocessing.cpu_count(),
      'build_configs': build_configs,
      'targets': GetBuildTargetFromCommandLine(cmdline),
  }

  jflag = GetJflag(cmdline)
  if jflag is not None:
    metadata['jobs'] = jflag

  return metadata


def GetNinjalog(cmdline):
  """GetNinjalog returns the path to ninjalog from cmdline."""
  # ninjalog is in current working directory by default.
  ninjalog_dir = '.'

  i = 0
  while i < len(cmdline):
    cmd = cmdline[i]
    i += 1
    if cmd == '-C' and i < len(cmdline):
      ninjalog_dir = cmdline[i]
      i += 1
      continue

    if cmd.startswith('-C') and len(cmd) > len('-C'):
      ninjalog_dir = cmd[len('-C'):]

  return os.path.join(ninjalog_dir, '.ninja_log')


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('--server',
                      default='chromium-build-stats.appspot.com',
                      help='server to upload ninjalog file.')
  parser.add_argument('--ninjalog', help='ninjalog file to upload.')
  parser.add_argument('--verbose',
                      action='store_true',
                      help='Enable verbose logging.')
  parser.add_argument('--cmdline',
                      required=True,
                      nargs=argparse.REMAINDER,
                      help='command line args passed to ninja.')

  args = parser.parse_args()

  if args.verbose:
    logging.basicConfig(level=logging.INFO)
  else:
    # Disable logging.
    logging.disable(logging.CRITICAL)

  if not IsGoogler(args.server):
    return 0

  ninjalog = args.ninjalog or GetNinjalog(args.cmdline)
  if not os.path.isfile(ninjalog):
    logging.warning("ninjalog is not found in %s", ninjalog)
    return 1

  # We assume that each ninja invocation interval takes at least 2 seconds.
  # This is not to have duplicate entry in server when current build is no-op.
  if os.stat(ninjalog).st_mtime < time.time() - 2:
    logging.info("ninjalog is not updated recently %s", ninjalog)
    return 0

  output = io.BytesIO()

  with open(ninjalog) as f:
    with gzip.GzipFile(fileobj=output, mode='wb') as g:
      g.write(f.read().encode())
      g.write(b'# end of ninja log\n')

      metadata = GetMetadata(args.cmdline, ninjalog)
      logging.info('send metadata: %s', json.dumps(metadata))
      g.write(json.dumps(metadata).encode())

  resp = request.urlopen(
      request.Request('https://' + args.server + '/upload_ninja_log/',
                      data=output.getvalue(),
                      headers={'Content-Encoding': 'gzip'}))

  if resp.status != 200:
    logging.warning("unexpected status code for response: %s", resp.status)
    return 1

  logging.info('response header: %s', resp.headers)
  logging.info('response content: %s', resp.read())
  return 0


if __name__ == '__main__':
  sys.exit(main())
