#!/usr/bin/env python2
# -*- 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$', line):
        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 '--- 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()
