# Copyright (c) 2012 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.


"""The package initialization and abstract base class for shop floor systems.

Every implementations should inherit ShopFloorBase and override the member
functions to interact with their real shop floor system.
"""

import csv
import glob
import logging
import os
import shutil
import time
import xmlrpclib

# In current implementation, we use xmlrpclib.Binary to prepare blobs.
from xmlrpclib import Binary

import factory_common
from cros.factory.shopfloor import factory_update_server, factory_log_server
from cros.factory.test import factory
from cros.factory.test import shopfloor
from cros.factory.test import utils
from cros.factory.test.registration_codes import CheckRegistrationCode
from cros.factory.utils.process_utils import Spawn


EVENTS_DIR = 'events'
INCREMENTAL_EVENTS_DIR = 'events_incremental'
REPORTS_DIR = 'reports'
AUX_LOGS_DIR = 'aux_logs'
UPDATE_DIR = 'update'
PARAMETERS_DIR = 'parameters'
FACTORY_LOG_DIR = 'system_logs'
REGISTRATION_CODE_LOG_CSV = 'registration_code_log.csv'
LOGS_DIR_FORMAT = 'logs.%Y%m%d'
HOURLY_DIR_FORMAT = 'logs.%Y%m%d-%H'

IN_PROGRESS_SUFFIX = '.INPROGRESS'


class NewlineTerminatedCSVDialect(csv.excel):
  lineterminator = '\n'


class ShopFloorException(Exception):
  pass


class ShopFloorBase(object):
  """Base class for shopfloor servers.

  :ivar data_dir: The top-level directory for shopfloor data.
  :ivar address: The IP address for the shopfloor server to bind on.
  :ivar port: The port for the shopfloor server to bind on.
  :ivar update_server: An FactoryUpdateServer for factory environment update.
  :ivar log_server: An FactoryLogServer for factory log files to be uploaded
   from DUT.
  :ivar _auto_archive_logs: An optional path to use for auto-archiving
   logs (see the --auto-archive-logs command-line argument).  This
   must contain the string 'DATE'.
  :ivar _auto_archive_logs_days: Number of days of logs to save.
  :ivar _auto_archive_logs_dir_exists: True if the parent of _auto_archive_logs
   existed the last time we checked, False if not, or None if we've
   never checked.
  """

  NAME = 'ShopFloorBase'
  VERSION = 4

  def __init__(self):
    self.data_dir = None  # Set by shopfloor_server
    self.address = None   # Set by shopfloor_server
    self.port = None      # Set by shopfloor_server
    self.update_dir = None
    self.parameters_dir = None
    self.update_server = None
    self.factory_log_dir = None
    self.log_server = None
    self.events_rotate_hourly = False
    self.reports_rotate_hourly = False
    self._auto_archive_logs = None
    self._auto_archive_logs_days = None
    self._auto_archive_logs_dir_exists = None

  def _InitBase(self, auto_archive_logs, auto_archive_logs_days, updater=None):
    """Initializes the base class.

    Args:
      auto_archive_logs: See _auto_archive_logs property.
      updater: A reference to factory updater. Factory updater provides
               interfaces compatible to FactoryUpdateServer. Including
               Start, Stop, hwid_path, GetTestMD5, NeedsUpdate and rsync_port.
    """
    if auto_archive_logs_days > 0 and auto_archive_logs:
      assert 'DATE' in auto_archive_logs, (
          '--auto-archive-logs flag must contain the string DATE')
      self._auto_archive_logs = auto_archive_logs
      self._auto_archive_logs_days = auto_archive_logs_days

    if not os.path.exists(self.data_dir):
      logging.warn('Data directory %s does not exist; creating it',
                   self.data_dir)
      os.makedirs(self.data_dir)

    if updater is None:
      # Dynamic test directory for holding updates is called "update" in
      # data_dir.
      self.update_dir = os.path.join(self.data_dir, UPDATE_DIR)
      utils.TryMakeDirs(self.update_dir)
      self.update_dir = os.path.realpath(self.update_dir)
      self.update_server = factory_update_server.FactoryUpdateServer(
          self.update_dir,
          rsyncd_addr=self.address,
          rsyncd_port=(self.port + 1),
          on_idle=(self._AutoSaveLogs if self._auto_archive_logs else None))
      # Create factory log directory
      self.factory_log_dir = os.path.join(self.data_dir, FACTORY_LOG_DIR)
      utils.TryMakeDirs(self.factory_log_dir)
      self.factory_log_dir = os.path.realpath(self.factory_log_dir)
      self.log_server = factory_log_server.FactoryLogServer(
          self.factory_log_dir,
          rsyncd_addr=self.address,
          rsyncd_port=(self.port + 2))
    else:
      # Use external update server and log server
      self.update_server = updater
      self.log_server = updater
      # When using external updater, events and reports rotate hourly
      # TODO(rongchang): modify internal auto log archive
      self.reports_rotate_hourly = True
      self.events_rotate_hourly = True
    # Create parameters directory
    self.parameters_dir = os.path.join(self.data_dir, PARAMETERS_DIR)
    utils.TryMakeDirs(self.parameters_dir)
    self.parameters_dir = os.path.realpath(self.parameters_dir)

  def _StartBase(self):
    """Starts the base class."""
    if self.update_server:
      logging.debug('Starting factory update server...')
      self.update_server.Start()
    logging.debug('Starting factory log server...')
    self.log_server.Start()

  def _StopBase(self):
    """Stops the base class."""
    if self.update_server:
      self.update_server.Stop()
    self.log_server.Stop()

  def _AutoSaveLogs(self):
    """Implements functionality to automatically save logs to USB.

    (See the description of the --auto-archive-logs command-line argument
    for details.)
    """
    auto_archive_dir = os.path.dirname(self._auto_archive_logs)
    new_auto_archive_logs_dir_exists = os.path.isdir(auto_archive_dir)
    if new_auto_archive_logs_dir_exists != self._auto_archive_logs_dir_exists:
      # If the auto-archive directory is newly present (or not present),
      # log a message.
      if new_auto_archive_logs_dir_exists:
        logging.info('Auto-archive directory %s found; will auto-archive '
                     "past %d days' logs there if not present",
                     auto_archive_dir, self._auto_archive_logs_days)
      else:
        logging.info('Auto-archive directory %s not found; create it (or mount '
                     "media there) to auto-archive past %d days' logs",
                     auto_archive_dir, self._auto_archive_logs_days)
      self._auto_archive_logs_dir_exists = new_auto_archive_logs_dir_exists

    if new_auto_archive_logs_dir_exists:
      for days_ago in xrange(1, self._auto_archive_logs_days + 1):
        past_day = time.localtime(time.time() - days_ago * 86400)
        past_day_logs_dir_name = time.strftime(LOGS_DIR_FORMAT, past_day)
        archive_name = os.path.join(
            self._auto_archive_logs.replace(
                'DATE', time.strftime('%Y%m%d', past_day)))
        if os.path.exists(archive_name):
          # We've already done this.
          continue

        past_day_logs_dir = os.path.join(self.data_dir, REPORTS_DIR,
                                         past_day_logs_dir_name)
        if not os.path.exists(past_day_logs_dir):
          # There aren't any logs from past_day.
          continue

        in_progress_name = archive_name + IN_PROGRESS_SUFFIX
        logging.info('Archiving %s to %s', past_day_logs_dir, archive_name)

        have_pbzip2 = Spawn(
            ['which', 'pbzip2'],
            ignore_stdout=True, ignore_stderr=True, call=True).returncode == 0

        Spawn(['tar', '-I', 'pbzip2' if have_pbzip2 else 'bzip2',
               '-cf', in_progress_name,
               '-C', os.path.join(self.data_dir, REPORTS_DIR),
               past_day_logs_dir_name],
              check_call=True, log=True, log_stderr_on_error=True)
        shutil.move(in_progress_name, archive_name)
        logging.info('Finishing archiving %s to %s',
                     past_day_logs_dir, archive_name)

  def SaveReport(self, report_name, report_blob):
    """Saves a report to disk and checks its integrity.

    Args:
      report_path: Name of the report.
      report_blob: Contents of the report.

    Raises:
      ShopFloorException on error.
    """
    report_path = os.path.join(self.GetReportsDir(), report_name)
    in_progress_path = report_path + IN_PROGRESS_SUFFIX
    try:
      with open(in_progress_path, 'wb') as f:
        f.write(report_blob)
      self.CheckReportIntegrity(in_progress_path)
      shutil.move(in_progress_path, report_path)
    finally:
      try:
        # Attempt to remove the in-progress file (e.g., if the
        # integrity check failed)
        os.unlink(in_progress_path)
      except OSError:
        pass

  def CheckReportIntegrity(self, report_path):
    """Checks the integrity of a report.

    This checks to make sure that "tar tf" on the report does not return any
    errors, and that the report contains var/factory/log/factory.log.

    Raises:
      ShopFloorException on error.
    """
    process = Spawn(['tar', '-tf', report_path], log=True,
                    read_stdout=True, read_stderr=True)

    if process.returncode:
      error = 'Corrupt report: tar failed'
    elif (factory.FACTORY_LOG_PATH_ON_DEVICE.lstrip('/') not in
          process.stdout_data.split('\n')):
      error = 'Corrupt report: %s missing' % (
          factory.FACTORY_LOG_PATH_ON_DEVICE.lstrip('/'))
    else:
      # OK!  Save the MD5SUM (removing the INPROGRESS suffix if any)
      # and return.
      md5_path = report_path
      if report_path.endswith(IN_PROGRESS_SUFFIX):
        md5_path = md5_path[:-len(IN_PROGRESS_SUFFIX)]
      md5_path += '.md5'
      try:
        with open(md5_path, 'w') as f:
          Spawn(['md5sum', report_path], stdout=f, check_call=True)
      except:
        try:
          os.unlink(md5_path)
        except OSError:
          pass
        raise
      return

    error += ': tar returncode=%d, stderr=%r' % (
        process.returncode, process.stderr_data)
    logging.error(error)
    raise ShopFloorException(error)

  def GetLogsDir(self, subdir=None, log_format=LOGS_DIR_FORMAT):
    """Returns the active logs directory.

    This is the data directory base plus a path element 'subdir'. When
    log_format is not None, it creates one more level of log folder to
    rotate the logs. Default log_format is "logs.YYMMDD", where YYMMDD
    is today's date in the local time zone.  This creates the directory
    if it does not exist.

    Args:
      subdir: If not None, this is appended to the path.
      log_format: strftime log format for log rotation.
    """
    ret = self.data_dir
    if subdir:
      ret = os.path.join(ret, subdir)
      utils.TryMakeDirs(ret)
    if log_format:
      ret = os.path.join(ret, time.strftime(log_format))
      utils.TryMakeDirs(ret)
    return ret

  def SetEventHourlyRotation(self, value):
    """Enables the option for additional hourly rotation of events."""
    self.events_rotate_hourly = value
    return self.events_rotate_hourly

  def SetReportHourlyRotation(self, value):
    """Enables the option for hourly rotation of reports."""
    self.reports_rotate_hourly = value
    return self.reports_rotate_hourly

  def GetEventsDir(self):
    """Returns the active events directory."""
    return self.GetLogsDir(EVENTS_DIR, log_format=None)

  def GetIncrementalEventsDir(self):
    """Returns the active incremental events directory."""
    return self.GetLogsDir(INCREMENTAL_EVENTS_DIR, log_format=HOURLY_DIR_FORMAT)

  def GetReportsDir(self):
    """Returns the active reports directory."""
    if self.reports_rotate_hourly:
      return self.GetLogsDir(REPORTS_DIR, log_format=HOURLY_DIR_FORMAT)
    return self.GetLogsDir(REPORTS_DIR)

  def GetAuxLogsDir(self):
    """Returns the active auxiliary logs directory."""
    return self.GetLogsDir(AUX_LOGS_DIR)

  def Init(self):
    """Initializes the shop floor system.

    Subclasses should implement this rather than __init__.
    """
    pass

  def Ping(self):
    """Always returns true (for client to check if server is working)."""
    return True

  def CheckSN(self, serial):
    """Checks whether a serial number is valid.

    Args:
      serial: A string of device serial number.

    Returns:
      True if the serial number provided is considered valid.

    Raises:
      ValueError if serial is invalid, or other exceptions defined by individual
      modules. Note this will be converted to xmlrpclib.Fault when being used as
      a XML-RPC server module.
    """
    raise NotImplementedError('CheckSN')

  def ListParameters(self, pattern):
    """Lists files that match the pattern in parameters directory.

     Args:
       pattern: A pattern string for glob to list matched files.

     Returns:
       A list of matched files.

     Raises:
       ValueError if caller is trying to query outside parameters directory.
    """
    glob_pathname = os.path.abspath(os.path.join(self.parameters_dir, pattern))
    if not glob_pathname.startswith(self.parameters_dir):
      raise ValueError('ListParameters is limited to parameter directory')

    matched_file = glob.glob(glob_pathname)
    # Only return files.
    matched_file = filter(os.path.isfile, matched_file)
    return [os.path.relpath(x, self.parameters_dir) for x in matched_file]

  # TODO(itspeter): Implement DownloadParameter.
  def GetParameter(self, path):
    """Gets the assigned parameter file.

     Args:
       path: A relative path for locating the parameter.

     Returns:
       Content of the parameter. It is always wrapped in a shopfloor.Binary
       object to provides best flexibility.

     Raises:
       ValueError if the parameter does not exist or is not under
       parameters folder.
    """
    abspath = os.path.abspath(os.path.join(self.parameters_dir, path))
    if not abspath.startswith(self.parameters_dir):
      raise ValueError('GetParameter is limited to parameter directory')

    if not os.path.isfile(abspath):
      raise ValueError('File does not exist or it is not a file')

    return Binary(open(abspath).read())

  def GetHWID(self, serial):
    """Returns appropriate HWID according to given serial number.

    Args:
      serial: A string of device serial number.

    Returns:
      The associated HWID string.

    Raises:
      ValueError if serial is invalid, or other exceptions defined by individual
      modules. Note this will be converted to xmlrpclib.Fault when being used as
      a XML-RPC server module.
    """
    raise NotImplementedError('GetHWID')

  def GetHWIDUpdater(self):
    """Returns a HWID updater bundle, if available.

    Returns:
      The binary-encoded contents of a file named 'hwid_*' in the data
      directory.  If there are no such files, returns None.

    Raises:
      ShopFloorException if there are >1 HWID bundles available.
    """
    path = self.update_server.hwid_path
    return Binary(open(path).read()) if path else None

  def GetVPD(self, serial):
    """Returns VPD data to set (in dictionary format).

    Args:
      serial: A string of device serial number.

    Returns:
      VPD data in dict {'ro': dict(), 'rw': dict()}

    Raises:
      ValueError if serial is invalid, or other exceptions defined by individual
      modules. Note this will be converted to xmlrpclib.Fault when being used as
      a XML-RPC server module.
    """
    raise NotImplementedError('GetVPD')

  def UploadReport(self, serial, report_blob, report_name=None):
    """Uploads a report file.

    Args:
      serial: A string of device serial number.
      report_blob: Blob of compressed report to be stored (must be prepared by
          shopfloor.Binary)
      report_name: (Optional) Suggested report file name. This is uslally
          assigned by factory test client programs (ex, gooftool); however
          server implementations still may use other names to store the report.

    Returns:
      True on success.

    Raises:
      ValueError if serial is invalid, or other exceptions defined by individual
      modules. Note this will be converted to xmlrpclib.Fault when being used as
      a XML-RPC server module.
    """
    raise NotImplementedError('UploadReport')

  def SaveAuxLog(self, name, contents):
    """Saves an auxiliary log into the logs.$(DATE)/aux_logs directory.

    In general, this should probably be compressed to save space.

    Args:
      name: Name of the report.  Any existing log with the same name will be
        overwritten.  Subdirectories are allowed.
      contents: Contents of the report.  If this is binary, it should be
        wrapped in a shopfloor.Binary object.
    """
    contents = self.UnwrapBlob(contents)

    # Disallow absolute paths and paths with '..'.
    assert not os.path.isabs(name)
    assert '..' not in os.path.split(name)

    path = os.path.join(self.GetAuxLogsDir(), name)
    utils.TryMakeDirs(os.path.dirname(path))
    with open(path, 'wb') as f:
      f.write(contents)

  def Finalize(self, serial):
    """Marks target device (by serial) to be ready for shipment.

    Args:
      serial: A string of device serial number.

    Returns:
      True on success.

    Raises:
      ValueError if serial is invalid, or other exceptions defined by individual
      modules. Note this will be converted to xmlrpclib.Fault when being used as
      a XML-RPC server module.
    """
    raise NotImplementedError('Finalize')

  def GetRegistrationCodeMap(self, serial):
    """Returns the registration code map for the given serial number.

    Returns:
      {'user': registration_code, 'group': group_code}

    Raises:
      ValueError if serial is invalid, or other exceptions defined by individual
      modules. Note this will be converted to xmlrpclib.Fault when being used as
      a XML-RPC server module.
    """
    raise NotImplementedError('GetRegistrationCode')

  def GetAuxData(self, table_name, id):  # pylint: disable=W0622
    """Returns a row from an auxiliary table.

    Args:
      table_name: The table containing the desired row.
      id: The ID of the row to return.

    Returns:
      A map of properties from the given table.

    Raises:
      ValueError if the ID cannot be found in the table.  Note this will be
      converted to xmlrpclib.Fault when being used as an XML-RPC server
      module.
    """
    raise NotImplementedError('GetAuxData')

  def LogRegistrationCodeMap(self, hwid, registration_code_map,
                             log_filename='registration_code_log.csv',
                             board=None):
    """Logs that a particular registration code has been used.
    Args:
      hwid: HWID object, could be None.
      registration_code_map: A dict contains 'user' and 'group' reg code.
      log_filename: File to append log to.
      board: Board name. If None, will try to derive it from hwid.

    Raises:
      ValueError if the registration code is invalid.
      ValueError if both board and hwid are None.
    """
    for key in ('user', 'group'):
      CheckRegistrationCode(registration_code_map[key])

    if not board:
      if hwid:
        board = hwid.partition(' ')[0]
      else:
        raise ValueError('Both board and hwid are missing.')

    if not hwid:
      hwid = ''

    # See http://goto/nkjyr for file format.
    with open(os.path.join(self.data_dir, log_filename), 'ab') as f:
      csv.writer(f, dialect=NewlineTerminatedCSVDialect).writerow([
          board,
          registration_code_map['user'],
          registration_code_map['group'],
          time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime()),
          hwid])
      os.fdatasync(f.fileno())

  def GetFactoryLogPort(self):
    """Returns the port to use for rsync factory logs.

    Returns:
      The port, or None if there is no factory log server available.
    """
    return self.log_server.rsyncd_port if self.log_server else None

  def GetTestMd5sum(self):
    """Gets the latest md5sum of dynamic test tarball.

    Returns:
      A string of md5sum.  None if no dynamic test tarball is installed.
    """
    return self.update_server.GetTestMd5sum()

  def NeedsUpdate(self, device_md5sum):
    """Checks if the device with device_md5sum needs an update."""
    return self.update_server.NeedsUpdate(device_md5sum)

  def GetUpdatePort(self):
    """Returns the port to use for rsync updates.

    Returns:
      The port, or None if there is no update server available.
    """
    return self.update_server.rsyncd_port if self.update_server else None

  def UploadEvent(self, log_name, chunk):
    """Uploads a chunk of events.

    In addition to append events to a single file, we appends event to a
    directory that split on an hourly basis in order to fetch events in a timely
    approach if events_rotate_hourly flag set to True.

    Args:
      log_name: A string of the event log filename. Event logging module creates
          event files with an unique identifier (uuid) as part of the filename.
      chunk: A string containing one or more events. Events are in YAML format
          and separated by a "---" as specified by YAML. A chunk contains one or
          more events with separator.

    Returns:
      True on success.

    Raises:
      IOError if unable to save the chunk of events.
    """
    chunk = self.UnwrapBlob(chunk)

    log_file = os.path.join(self.GetEventsDir(), log_name)
    with open(log_file, 'a') as f:
      f.write(chunk)

    # Wrote events split on an hourly basis
    if self.events_rotate_hourly:
      log_file = os.path.join(self.GetIncrementalEventsDir(), log_name)
      with open(log_file, 'a') as f:
        f.write(chunk)

    return True

  def GetTime(self):
    """Returns the current time in seconds since the epoch."""
    return time.time()

  def UnwrapBlob(self, blob):
    """Unwraps a blob object."""
    return blob.data if isinstance(blob, Binary) else blob


# Alias ShopFloorBase to ShopFloor, so that this module can be run directly.
ShopFloor = ShopFloorBase
