# -*- coding: utf-8 -*-
# Copyright 2019 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.

"""Unittests for goma_lib.py"""

from __future__ import print_function

import datetime
import getpass
import gzip
import json
import os
import sys
import time

from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import goma_lib
from chromite.lib import osutils


assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'


class TestLogsArchiver(cros_test_lib.MockTempDirTestCase):
  """Tests for goma_lib.LogsArchiver."""

  def setUp(self):
    self.goma_log_dir = os.path.join(self.tempdir, 'goma_log_dir')
    osutils.SafeMakedirs(self.goma_log_dir)
    self.dest_dir = os.path.join(self.tempdir, 'destination_dir')
    osutils.SafeMakedirs(self.dest_dir)

  def _CreateFile(self, name):
    """Creates a basic file, such as a stats or counterz file.

    Args:
      name (str): Filename
    """
    osutils.WriteFile(os.path.join(self.goma_log_dir, name), 'File: ' + name)

  def _CreateLogFile(self, name, timestamp):
    """Creates a log file for testing.

    Args:
      name (str): Log file name.
      timestamp (datetime): timestamp that is written to the file.
    """
    path = os.path.join(
        self.goma_log_dir,
        '%s.host.log.INFO.%s' % (name, timestamp.strftime('%Y%m%d-%H%M%S.%f')))
    osutils.WriteFile(
        path,
        timestamp.strftime('Log file created at: %Y/%m/%d %H:%M:%S'))

  def testArchive(self):
    """Test successful archive of goma logs without stats/counterz specified."""
    self._CreateLogFile(
        'compiler_proxy', datetime.datetime(2017, 4, 26, 12, 0, 0))
    self._CreateLogFile(
        'compiler_proxy-subproc', datetime.datetime(2017, 4, 26, 12, 0, 0))
    self._CreateLogFile(
        'gomacc', datetime.datetime(2017, 4, 26, 12, 1, 0))
    self._CreateLogFile(
        'gomacc', datetime.datetime(2017, 4, 26, 12, 2, 0))

    archiver = goma_lib.LogsArchiver(self.goma_log_dir, dest_dir=self.dest_dir)
    archiver_tuple = archiver.Archive()

    # Verify that no stats/counterz was returned in the tuple.
    self.assertFalse(archiver_tuple.counterz_file)
    self.assertFalse(archiver_tuple.stats_file)

    archived_files = os.listdir(self.dest_dir)

    # Verify that the list of files returned matched what we find in the
    # dest_dir.
    self.assertCountEqual(archiver_tuple.log_files, archived_files)

    self.assertCountEqual(
        archived_files,
        ['compiler_proxy.host.log.INFO.20170426-120000.000000.gz',
         'gomacc.host.log.INFO.20170426-120100.000000.tar.gz',
         'compiler_proxy-subproc.host.log.INFO.20170426-120000.000000.gz'])

  def testArchiveWithStatsAndCounterz(self):
    """Test successful archive of goma logs with stats and counterz."""
    self._CreateLogFile(
        'compiler_proxy', datetime.datetime(2017, 4, 26, 12, 0, 0))
    self._CreateLogFile(
        'compiler_proxy-subproc', datetime.datetime(2017, 4, 26, 12, 0, 0))
    self._CreateLogFile(
        'gomacc', datetime.datetime(2017, 4, 26, 12, 1, 0))
    self._CreateLogFile(
        'gomacc', datetime.datetime(2017, 4, 26, 12, 2, 0))
    self._CreateFile('stats.binaryproto')
    self._CreateFile('counterz.binaryproto')

    archiver = goma_lib.LogsArchiver(self.goma_log_dir, dest_dir=self.dest_dir,
                                     stats_file='stats.binaryproto',
                                     counterz_file='counterz.binaryproto')
    archiver_tuple = archiver.Archive()

    self.assertCountEqual(
        archiver_tuple.log_files,
        ['compiler_proxy.host.log.INFO.20170426-120000.000000.gz',
         'gomacc.host.log.INFO.20170426-120100.000000.tar.gz',
         'compiler_proxy-subproc.host.log.INFO.20170426-120000.000000.gz'])
    self.assertEqual(archiver_tuple.stats_file, 'stats.binaryproto')
    self.assertEqual(archiver_tuple.counterz_file, 'counterz.binaryproto')

  def testArchiveWithStatsAndMissingCounterz(self):
    """Test successful archive of goma logs with stats and counterz."""
    self._CreateLogFile(
        'compiler_proxy', datetime.datetime(2017, 4, 26, 12, 0, 0))
    self._CreateLogFile(
        'compiler_proxy-subproc', datetime.datetime(2017, 4, 26, 12, 0, 0))
    self._CreateLogFile(
        'gomacc', datetime.datetime(2017, 4, 26, 12, 1, 0))
    self._CreateLogFile(
        'gomacc', datetime.datetime(2017, 4, 26, 12, 2, 0))
    self._CreateFile('stats.binaryproto')

    archiver = goma_lib.LogsArchiver(self.goma_log_dir, dest_dir=self.dest_dir,
                                     stats_file='stats.binaryproto',
                                     counterz_file='counterz.binaryproto')
    # Because counterz.binaryproto does not exist, verify it is not returned
    # as one of the files archived.
    archiver_tuple = archiver.Archive()
    self.assertFalse(archiver_tuple.counterz_file)
    self.assertEqual(archiver_tuple.stats_file, 'stats.binaryproto')
    self.assertCountEqual(
        archiver_tuple.log_files,
        ['compiler_proxy.host.log.INFO.20170426-120000.000000.gz',
         'gomacc.host.log.INFO.20170426-120100.000000.tar.gz',
         'compiler_proxy-subproc.host.log.INFO.20170426-120000.000000.gz'])

  def testNinjaLogArchive(self):
    """Test successful archive of ninja logs."""
    self._CreateLogFile(
        'compiler_proxy', datetime.datetime(2017, 8, 21, 12, 0, 0))
    self._CreateLogFile(
        'compiler_proxy-subproc', datetime.datetime(2017, 8, 21, 12, 0, 0))

    ninja_log_path = os.path.join(self.goma_log_dir, 'ninja_log')
    osutils.WriteFile(ninja_log_path, 'Ninja Log Content\n')
    timestamp = datetime.datetime(2017, 8, 21, 12, 0, 0)
    mtime = time.mktime(timestamp.timetuple())
    os.utime(ninja_log_path, ((time.time(), mtime)))

    osutils.WriteFile(
        os.path.join(self.goma_log_dir, 'ninja_command'), 'ninja_command')
    osutils.WriteFile(
        os.path.join(self.goma_log_dir, 'ninja_cwd'), 'ninja_cwd')
    osutils.WriteFile(
        os.path.join(self.goma_log_dir, 'ninja_env'),
        'key1=value1\0key2=value2\0')
    osutils.WriteFile(
        os.path.join(self.goma_log_dir, 'ninja_exit'), '0')

    archiver = goma_lib.LogsArchiver(self.goma_log_dir, dest_dir=self.dest_dir)
    archived_tuple = archiver.Archive()

    username = getpass.getuser()
    pid = os.getpid()
    hostname = cros_build_lib.GetHostName()
    ninjalog_filename = 'ninja_log.%s.%s.20170821-120000.%d.gz' % (
        username, hostname, pid)
    # Verify the archived files in the dest_dir
    archived_files = os.listdir(self.dest_dir)
    self.assertCountEqual(
        archived_files,
        [ninjalog_filename,
         'compiler_proxy-subproc.host.log.INFO.20170821-120000.000000.gz',
         'compiler_proxy.host.log.INFO.20170821-120000.000000.gz'])
    # Verify the archived_tuple result.
    self.assertFalse(archived_tuple.counterz_file)
    self.assertFalse(archived_tuple.stats_file)
    self.assertCountEqual(
        archived_tuple.log_files,
        ['compiler_proxy.host.log.INFO.20170821-120000.000000.gz',
         'compiler_proxy-subproc.host.log.INFO.20170821-120000.000000.gz',
         ninjalog_filename])


    # Verify content of ninja_log file.
    ninjalog_path = os.path.join(self.dest_dir, ninjalog_filename)

    with gzip.open(ninjalog_path, 'rt') as gzip_file:
      ninja_log_content = gzip_file.read()

    content, eof, metadata_json = ninja_log_content.split('\n', 3)
    self.assertEqual('Ninja Log Content', content)
    self.assertEqual('# end of ninja log', eof)
    metadata = json.loads(metadata_json)
    self.assertEqual(
        metadata,
        {
            'platform': 'chromeos',
            'cmdline': ['ninja_command'],
            'cwd': 'ninja_cwd',
            'exit': 0,
            'env': {'key1': 'value1', 'key2': 'value2'},
            'compiler_proxy_info':
            'compiler_proxy.host.log.INFO.20170821-120000.000000'
        })
