# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Uploads goma log info to storage.

Note that build/ has similar concept scripts.
cf)
https://chromium.googlesource.com/chromium/tools/build/+/master/scripts/slave/goma_utils.py
https://chromium.googlesource.com/chromium/tools/build/+/master/scripts/slave/upload_goma_logs.py

These and this scripts should be maintained in almost sync.
"""

from __future__ import print_function

import collections
import datetime
import glob
import json
import os
import re

from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import gs


# The Google Cloud Storage bucket to store logs related to goma.
GOMA_LOG_GS_BUCKET = 'chrome-goma-log'

# Timestamp format in a log file.
_TIMESTAMP_PATTERN = re.compile(r'(\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2})')
_TIMESTAMP_FORMAT = '%Y/%m/%d %H:%M:%S'

_GOMA_LOG_URL_TEMPLATE = (
    'http://chromium-build-stats.appspot.com/compiler_proxy_log/%s/%s')

def _GetGomaLogDirectory():
  """Returns goma's log directory.

  Returns:
    a string of a directory name where goma's log may exist.
  """
  candidates = ['GLOG_log_dir', 'GOOGLE_LOG_DIR', 'TEST_TMPDIR',
                'TMPDIR', 'TMP']
  for candidate in candidates:
    value = os.environ.get(candidate)
    if value and os.path.isdir(value):
      return value

  # Fallback to /tmp.
  return '/tmp'


def _GetLogFileTimestamp(path):
  """Returns timestamp when the given glog log was created.

  Args:
    path: a path to a google-glog log file.

  Returns:
    datetime.datetime instance when the log file was created.
    Or, None, if it is not a glog file.
  """
  with open(path) as f:
    # Test the first line only.
    matched = _TIMESTAMP_PATTERN.search(f.readline())
    if matched:
      return datetime.datetime.strptime(matched.group(1), _TIMESTAMP_FORMAT)
  return None


def _GetBuilderInfo():
  """Returns builder info containing bot info."""
  # Use OrderedDict for json output stabilization.
  return collections.OrderedDict([
      ('builder', os.environ.get('BUILDBOT_BUILDERNAME', '')),
      ('master', os.environ.get('BUILDBOT_MASTERNAME', '')),
      ('slave', os.environ.get('BUILDBOT_SLAVENAME', '')),
      ('clobber', bool(os.environ.get('BUILDBOT_CLOBBER'))),
      ('os', 'chromeos'),
  ])


class GomaLogUploader(object):
  """Manages uploading goma log files to Google Cloud Storage."""

  # Special object to find latest log file. Please see _GetGlogInfoFileList()
  # for details.
  _LATEST = object()

  def __init__(self, goma_log_dir=None, dry_run=False):
    self._gs_context = gs.GSContext(dry_run=dry_run)
    self._goma_log_dir = goma_log_dir or _GetGomaLogDirectory()
    logging.info('Goma log directory is: %s', self._goma_log_dir)

  def _GetGlogInfoFileList(self, pattern, start_timestamp):
    """Returns filepaths of the google glog INFO file.

    Args:
      pattern: a string of INFO file pattern.
      start_timestamp: datetime.datetime instance or special object _LATEST.
        if datetime.datetime instance is passed, returns files after the
        timestamp. If timestamp is _LATEST, then returns the latest one only
        (i.e., the returned list contains only one filepath).

    Returns:
      a list of found glog INFO files in fullpath.
      Or, an empty list if not found.
    """
    info_pattern = os.path.join(self._goma_log_dir, '%s.*.INFO.*' % pattern)
    candidates = glob.glob(info_pattern)
    if not candidates:
      return []

    if start_timestamp is GomaLogUploader._LATEST:
      return [max(candidates)]

    # Sort in ascending order for stabilization.
    return sorted(path for path in candidates
                  if _GetLogFileTimestamp(path) > start_timestamp)

  def _GetCompilerProxyStartTime(self):
    """Returns timestamp when the latest compiler_proxy started."""
    # Returns the latest compiler_proxy's log file created timing.
    compiler_proxy_info_list = self._GetGlogInfoFileList(
        'compiler_proxy', GomaLogUploader._LATEST)
    if not compiler_proxy_info_list:
      return None
    return _GetLogFileTimestamp(compiler_proxy_info_list[0])

  def _UploadToGomaLogGS(self, path, remote_dir, headers):
    """Uploads the file to GS with gzip'ing.

    Args:
      path: local file path to be uploaded.
      remote_dir: path to the gs remote directory.
      headers: builder info to be annotated.
    """
    logging.info('Uploading %s', path)
    self._gs_context.CopyInto(
        path, remote_dir, filename=os.path.basename(path) + '.gz',
        auto_compress=True, headers=headers)

  def _UploadInfoFiles(self, remote_dir, headers, pattern, start_timestamp):
    """Uploads INFO files matched.

    Finds files whose path matches with pattern, and created after
    start_timestamp, then uploads it with gzip'ing.

    Args:
      remote_dir: path to the gs remote directory.
      headers: builder info to be annotated.
      pattern: matching path pattern.
      start_timestamp: files created after this timestamp will be uploaded.
        Can be _LATEST if latest one should be uploaded.

    Returns:
      A list of uploaded file paths.
    """
    paths = self._GetGlogInfoFileList(pattern, start_timestamp)
    if not paths:
      logging.warning('No glog files matched with: %s', pattern)
      return []

    for path in paths:
      self._UploadToGomaLogGS(path, remote_dir, headers)
    return paths

  def Upload(self, today=None):
    """Uploads goma related INFO files to Google Cloud Storage.

    Args:
      today: datetime.date instance representing today. This is introduced for
        testing purpose, because datetime.date is unpatchable.
        In real use case, this must be None.

    Returns:
      URL to the simple log viewer.
    """
    if today is None:
      today = datetime.date.today()
    dest_path = '%s/%s' % (
        today.strftime('%Y/%m/%d'), cros_build_lib.GetHostName())
    remote_dir = 'gs://%s/%s' % (GOMA_LOG_GS_BUCKET, dest_path)

    builder_info = json.dumps(_GetBuilderInfo())
    logging.info('BuilderInfo: %s', builder_info)
    headers = ['x-goog-meta-builderinfo:' + builder_info]

    self._UploadInfoFiles(
        remote_dir, headers, 'compiler_proxy-subproc', GomaLogUploader._LATEST)
    compiler_proxy_paths = self._UploadInfoFiles(
        remote_dir, headers, 'compiler_proxy', GomaLogUploader._LATEST)
    compiler_proxy_start_time = self._GetCompilerProxyStartTime()
    if not compiler_proxy_start_time:
      logging.error('Compiler proxy start time is not found. '
                    'So, gomacc INFO files will not be uploaded.')

    # TODO(crbug.com/719843): Enable uploading gomacc logs after
    # crbug.com/719843 is resolved.

    # Build the URL to the compiler_proxy log viewer.
    if not compiler_proxy_paths:
      logging.error('Compiler proxy file was not found.')
      return None
    return _GOMA_LOG_URL_TEMPLATE % (
        dest_path, os.path.basename(compiler_proxy_paths[0]) + '.gz')


def _GetParser():
  """Returns parser for upload_goma_info.

  Returns:
    commandline.ArgumentParser object to parse the commandline args.
  """
  parser = commandline.ArgumentParser()
  parser.add_argument('--dry-run', action='store_true',
                      help='If set, do not run actual gsutil commands.')
  return parser


def main(argv):
  parser = _GetParser()
  options = parser.parse_args(argv)
  options.Freeze()

  GomaLogUploader(dry_run=options.dry_run).Upload()
