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

"""A progress class for tracking CrOS auto-update process.

This class is mainly designed for:
  1. Set the pattern for generating the filenames of
     track_status_file/execute_log_file.
     track_status_file: Used for record the current step of CrOS auto-update
                        process. Only has one line.
     execute_log_file: Used for record the whole logging info of the CrOS
                       auto-update process, including any debug information.
  2. Write current auto-update process into the track_status_file.
  3. Read current auto-update process from the track_status_file.

This file also offers external functions that are related to add/check/delete
the progress of the CrOS auto-update process.
"""

from __future__ import print_function

import datetime
import glob
import logging
import os
import re

import log_util

# Module-local log function.
def _Log(message, *args):
  return log_util.LogWithTag('CROS_UPDATE_PROGRESS', message, *args)

# only import setup_chromite before chromite import.
import setup_chromite # pylint: disable=unused-import
try:
  from chromite.lib import osutils
except ImportError as e:
  _Log('chromite cannot be imported: %r', e)
  osutils = None


# Path for status tracking log.
_TRACK_LOG_FILE_PATH = '/tmp/auto-update/tracking_log/%s_%s.log'

# Pattern for status tracking log filename.
_TRACK_LOG_FILE_NAME_PATTERN = r'([^_]+)_([^_]+).log'

# The gap hour used in checking AU processes' count.
AU_PROCESS_HOUR_GAP = 3

# Path for executing log.
_EXECUTE_LOG_FILE_PATH = '/tmp/auto-update/executing_log/%s_%s.log'

# Path and files for temporarily saving devserver codes, devserver and
# update engine log.
_CROS_UPDATE_TEMP_PATH = '/tmp/cros-update_%s_%s'

_CROS_HOSTLOG_PATTERN = 'devserver_hostlog*'

# The string for update process finished
FINISHED = 'Completed'
ERROR_TAG = 'Error'


def ReadOneLine(filename):
  """Read one line from file.

  Args:
    filename: The file to be read.
  """
  return open(filename, 'r').readline().rstrip('\n')


def IsProcessAlive(pid):
  """Detect whether a process is alive or not.

  Args:
    pid: The process id.
  """
  path = '/proc/%s/stat' % pid
  try:
    stat = ReadOneLine(path)
  except IOError:
    if not os.path.exists(path):
      return False

    raise

  return stat.split()[2] != 'Z'


def GetExecuteLogFile(host_name, pid):
  """Return the whole path of execute log file."""
  if not os.path.exists(os.path.dirname(_EXECUTE_LOG_FILE_PATH)):
    osutils.SafeMakedirs(os.path.dirname(_EXECUTE_LOG_FILE_PATH))

  return _EXECUTE_LOG_FILE_PATH % (host_name, pid)


def GetTrackStatusFile(host_name, pid):
  """Return the whole path of track status file."""
  if not os.path.exists(os.path.dirname(_TRACK_LOG_FILE_PATH)):
    osutils.SafeMakedirs(os.path.dirname(_TRACK_LOG_FILE_PATH))

  return _TRACK_LOG_FILE_PATH % (host_name, pid)


def GetAllTrackStatusFileByTime():
  """Return all track status files existing in TRACK_LOG_FILE_PATH.

  Returns:
    A track status file list ordered by created time reversely.
  """
  return sorted(glob.glob(_TRACK_LOG_FILE_PATH % ('*', '*')),
                key=os.path.getctime, reverse=True)


def ParsePidFromTrackLogFileName(track_log_filename):
  """Parse pid from a given track log file's name.

  The track log file's name for auto-update is fixed:
      hostname_pid.log

  This func is used to parse pid from a given track log file.

  Args:
    track_log_filename: the filename of the track log to be parsed.

  Returns:
    the parsed pid (int).
  """
  match = re.match(_TRACK_LOG_FILE_NAME_PATTERN, track_log_filename)
  try:
    return int(match.groups()[1])
  except (AttributeError, IndexError, ValueError) as e:
    _Log('Cannot parse pid from track log file %s: %s', track_log_filename, e)
    return None


def GetAllTrackStatusFileByHostName(host_name):
  """Return a list of existing track status files generated for a host."""
  return glob.glob(_TRACK_LOG_FILE_PATH % (host_name, '*'))


def GetAllRunningAUProcess():
  """Get all the ongoing AU processes' pids from tracking logs.

  This func only checks the tracking logs generated in latest several hours,
  which is for avoiding the case that 'there's a running process whose id is
  as the same as a previous AU process'.

  Returns:
    A list of background AU processes' pids.
  """
  pids = []
  now = datetime.datetime.now()
  track_log_list = GetAllTrackStatusFileByTime()
  # Only check log file created in 3 hours.
  for track_log in track_log_list:
    try:
      created_time = datetime.datetime.fromtimestamp(
          os.path.getctime(track_log))
      if now - created_time >= datetime.timedelta(hours=AU_PROCESS_HOUR_GAP):
        break

      pid = ParsePidFromTrackLogFileName(os.path.basename(track_log))
      if pid and IsProcessAlive(pid):
        pids.append(pid)
    except (ValueError, os.error) as e:
      _Log('Error happened in getting pid from %s: %s', track_log, e)

  return pids


def GetAUTempDirectory(host_name, pid):
  """Return the temp dir for storing codes and logs during auto-update."""
  au_tempdir = _CROS_UPDATE_TEMP_PATH % (host_name, pid)
  if not os.path.exists(au_tempdir):
    osutils.SafeMakedirs(au_tempdir)

  return au_tempdir


def ReadExecuteLogFile(host_name, pid):
  """Return the content of execute log file."""
  return osutils.ReadFile(GetExecuteLogFile(host_name, pid))


def ReadAUHostLogFiles(host_name, pid):
  """Returns a dictionary containing the devserver host log files."""
  au_dir = GetAUTempDirectory(host_name, pid)
  hostlog_filenames = glob.glob(os.path.join(au_dir, _CROS_HOSTLOG_PATTERN))
  hostlog_files = {}
  for f in hostlog_filenames:
    hostlog_files[os.path.basename(f)] = osutils.ReadFile(f)
  return hostlog_files


def DelTrackStatusFile(host_name, pid):
  """Delete the track status log."""
  osutils.SafeUnlink(GetTrackStatusFile(host_name, pid))


def DelExecuteLogFile(host_name, pid):
  """Delete the track status log."""
  osutils.SafeUnlink(GetExecuteLogFile(host_name, pid))


def DelAUTempDirectory(host_name, pid):
  """Delete the directory including auto-update-related logs."""
  osutils.RmDir(GetAUTempDirectory(host_name, pid))


class AUProgress(object):
  """Used for tracking the CrOS auto-update progress."""

  def __init__(self, host_name, pid):
    """Initialize a CrOS update progress instance.

    Args:
      host_name: The name of host, should be in the file_name of the status
        tracking file of auto-update process.
      pid: The process id, should be in the file_name too.
    """
    self.host_name = host_name
    self.pid = pid

  @property
  def track_status_file(self):
    """The track status file to record the CrOS auto-update progress."""
    return GetTrackStatusFile(self.host_name, self.pid)

  def WriteStatus(self, content):
    """Write auto-update progress into status tracking file.

    Args:
      content: The content to be recorded.
    """
    if not self.track_status_file:
      return

    try:
      with open(self.track_status_file, 'w') as out_log:
        out_log.write(content)
    except Exception as e:
      logging.error('Cannot write au status: %r', e)

  def ReadStatus(self):
    """Read auto-update progress from status tracking file."""
    with open(self.track_status_file, 'r') as out_log:
      return out_log.read().rstrip('\n')
