# coding=utf-8
"""
© 2013 LinkedIn Corp. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
from collections import defaultdict
import datetime
import gc
import logging
import os
import re
import numpy
from naarad.metrics.metric import Metric
import naarad.utils

logger = logging.getLogger('naarad.metrics.ProcMeminfoMetric')

class ProcMeminfoMetric(Metric):
  """
  logs of /proc/vmstat
  The raw log file is assumed to have a timestamp prefix of all lines. E.g. in the format of "2013-01-02 03:55:22.13456 compact_fail 36"
  The log lines can be generated by   'cat /proc/vmstat | sed "s/^/$(date +%Y-%m-%d\ %H:%M:%S.%05N)\t/" '  
  """

  sub_metrics = None
  
  def __init__ (self, metric_type, infile_list, hostname, output_directory, resource_path, label, ts_start, ts_end,
                rule_strings, important_sub_metrics, **other_options):
    Metric.__init__(self, metric_type, infile_list, hostname, output_directory, resource_path, label, ts_start, ts_end,
                    rule_strings, important_sub_metrics)

    # in particular, Section can specify a subset of all rows (default has 43 rows):  "sub_metrics=nr_free_pages nr_inactive_anon"
    for (key, val) in other_options.iteritems():
      setattr(self, key, val.split())   
      
    self.sub_metric_description = {
      'MemTotal': 'Total memory in KB',
      'MemFree': 'Total free memory in KB',
      'Buffers': 'Size of buffers in KB',
      'Cached': 'Size of page cache in KB',
     }    
     
 
  def parse(self):
    """
    Parse the vmstat file
    :return: status of the metric parse
    """
    file_status = True
    for input_file in self.infile_list:
      file_status = file_status and naarad.utils.is_valid_file(input_file)
      if not file_status:
        return False
    status = True
    data = {}  # stores the data of each column
    for input_file in self.infile_list:
      logger.info('Processing : %s',input_file)
      with open(input_file) as fh:
        for line in fh:
          words = line.split()        # [0] is day; [1] is seconds; [2] is field name:; [3] is value  [4] is unit
          if len(words) < 3:
            continue
          ts = words[0] + " " + words[1]
          if self.ts_out_of_range(ts):
            continue
          col = words[2].strip(':')
          # only process sub_metrics specified in config.
          if self.sub_metrics and col not in self.sub_metrics:
            continue
          # add unit to metric description; most of the metrics have 'KB'; a few others do not have unit, they are in number of pages
          if len(words) > 4 and words[4]:
            unit = words[4]
          else:
            unit = 'pages'
          self.sub_metric_unit[col] = unit
          # stores the values in data[] before finally writing out
          if col in self.column_csv_map:
            out_csv = self.column_csv_map[col]
          else:
            out_csv = self.get_csv(col)   #  column_csv_map[] is assigned in get_csv()
            data[out_csv] = []
          data[out_csv].append(ts + "," + words[3])
    #post processing, putting data in csv files;   
    for csv in data.keys():      
      self.csv_files.append(csv)
      with open(csv, 'w') as fh:
        fh.write('\n'.join(sorted(data[csv])))
    return status
