#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2018 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.
#
# Extracts memd logs from feedback report logs, and reproduces the original
# /var/log/memd directory, containing the file memd.parameters and one or more
# memd.clip{000,001,...}.log (the "clip" files) with the sampled data.  This is
# the format expected by memd-plot.py.

"""Extracts memd logs from feedback report logs."""

from __future__ import print_function

import argparse
import glob
import os
import re
import subprocess
import sys


def die(message):
  """Prints message and exits with failure status."""
  print('memd-extract.py:', message)
  sys.exit(1)


class Extractor(object):
  """Methods to reconstruct memd logs from a feedback report."""

  def __init__(self, args):
    """Constructor."""
    self._args = args
    self._timestamp_re = re.compile(r'\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\..*')

  def setup_outdir(self, outdir):
    """Sets up the output directory by creating or cleaning it as needed."""
    if not os.path.exists(outdir):
      os.mkdir(outdir)
      return

    if not os.path.isdir(outdir):
      die('output directory path %s exists but is not a directory' % outdir)

    files = glob.glob('%s/*' % outdir)
    clip_re = re.compile(r'^%s/*memd.clip\d\d\d\.log$' % outdir)
    for filename in files:
      if filename == 'memd.parameters' or clip_re.match(filename):
        os.remove(filename)

  def unzip_and_open(self, filename):
    """Unzips |filename| and opens system_logs.txt.

    Ensures that |filename| is a ZIP archive containing system_logs.txt,
    unzips it, and opens it.
    """
    list_output = subprocess.check_output(['unzip', '-l', filename])
    for line in list_output.splitlines():
      if re.match(r'.*system_logs.txt$', str(line, encoding='utf-8')):
        subprocess.check_call(['unzip', '-o', filename])
        return open('system_logs.txt', 'r')
    die('%s does not contain system_logs.txt' % filename)

  def extract_sections(self, filename):
    """Extracts memd-related sections of the feedback logs in |filename|.

    The contents of |filename| are expected to be in feedback log format.
    Opens |filename| (if needed, |filename| is first uncompressed into
    system_logs.txt) and returns the content of memd parameters and clip
    files from the feedback log.  The clips are expected to appear first (as
    per alphabetical order of the filenames).
    """
    if re.match(r'^.*\.zip', filename):
      input_file = self.unzip_and_open(filename)
    else:
      input_file = open(filename, 'r')

    # |memd_parameters| is an array of lines.
    memd_parameters = []
    # |memd_clip_lines| is an array of lines.
    memd_clip_lines = []
    scan_state_start, scan_state_clips, scan_state_parameters = range(3)
    scan_state = scan_state_start
    for line in input_file:
      # In the START state look for beginning of sections.
      if scan_state == scan_state_start:
        if line.startswith('memd clips=<multiline>'):
          scan_state = scan_state_clips
          continue
        if line.startswith('memd.parameters=<multiline>'):
          scan_state = scan_state_parameters
          continue
      if scan_state == scan_state_clips:
        if '--- END ---' in line:
          scan_state = scan_state_start
        else:
          memd_clip_lines.append(line)
      if scan_state == scan_state_parameters:
        if '--- END ---' in line:
          scan_state = scan_state_start
          # Assume memd.parameters comes after memd clips, thus we're done.
          break
        else:
          memd_parameters.append(line)

    if scan_state != scan_state_start:
      die('missing END line in multiline section')
    if len(memd_clip_lines) == 0:
      die('missing memd_clips section')
    if '--- START ---' not in memd_clip_lines[0]:
      die('missing START line in memd clips section')
    if '--- START ---' not in memd_parameters[0]:
      die('missing START line in memd.parameters section')

    memd_clips = self.extract_clips(memd_clip_lines[1:])
    return (memd_parameters[1:], memd_clips)

  def extract_clips(self, clip_lines):
    """Extracts the content of clip files.

    |clip_lines| contains lines from a feedback report, where all clip files
    are concatenated and need to be separated by looking at their two-line
    header.  Returns an array of array of lines, each element representing the
    content of a clip file.
    """
    clips = []
    this_clip = []
    for line in clip_lines:
      if self._timestamp_re.match(line):
        clips.append(this_clip)
        this_clip = []
      this_clip.append(line)
    clips.append(this_clip)
    return clips[1:]

  def run(self):
    """Extracts memd parameters and clip files from a feedback report log.

    The log may be compressed (*.zip) or plain text (all other file names).
    The output files are placed in the specified output directory.
    """
    outdir = self._args['outdir']
    self.setup_outdir(outdir)
    (parameters, clips) = self.extract_sections(self._args['input-file'])
    with open('%s/memd.parameters' % outdir, 'w') as f:
      for line in parameters:
        f.write(line)
    clip_number = 0
    for clip in clips:
      with open('%s/memd.clip%03d.log' % (outdir, clip_number), 'w') as f:
        clip_number += 1
        for line in clip:
          f.write(line)


def main():
  """Extracts memd logs from feedback report logs."""
  parser = argparse.ArgumentParser(
      description='Extract memd logs from feedback report logs.')
  parser.add_argument('input-file')
  parser.add_argument('-o', '--outdir', default='memd')
  extractor = Extractor(vars(parser.parse_args()))
  extractor.run()

main()
