/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hadoop.chukwa.extraction.demux.processor.mapper;


import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.HashMap;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

import org.apache.hadoop.chukwa.datacollection.writer.hbase.Annotation.Table;
import org.apache.hadoop.chukwa.extraction.engine.ChukwaRecord;
import org.apache.hadoop.chukwa.extraction.engine.ChukwaRecordKey;
import org.apache.hadoop.chukwa.extraction.demux.Demux;
import org.apache.hadoop.chukwa.util.RegexUtil;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.conf.Configuration;
import org.apache.log4j.Logger;

/**
 * TsProcessor is a generic processor that can be configured to find the timestamp
 * in the text of a record. By default, this class expects that a record
 * starts with a date in this format: <code>yyyy-MM-dd HH:mm:ss,SSS</code>
 * <P>
 * This format can be changed with the following configurations.
 * <UL>
 * <LI><code>TsProcessor.default.time.format</code> - Changes the default time
 * format used by all data types.</LI>
 * <LI><code>TsProcessor.time.format.[some_data_type]</code> - Overrides the default
 * format for a specific data type.</LI>
 * </UL>
 * If the time string is not at the beginning of the record you can configure a
 * regular expression to locate the timestamp text with either of the following
 * configurations. The text found in group 1 of the regular expression match
 * will be used with the configured date format.
 * <UL>
 * <LI><code>TsProcessor.default.time.regex</code> - Changes the default time
 * location regex of the time text for all data types.</LI>
 * <LI><code>TsProcessor.time.regex.[some_data_type]</code> - Overrides the
 * default time location regex for a specific data type.</LI>
 * </UL>
 *
 */
@Table(name="TsProcessor",columnFamily="log")
public class TsProcessor extends AbstractProcessor {
  static Logger log = Logger.getLogger(TsProcessor.class);

  public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss,SSS";
  public static final String DEFAULT_TIME_REGEX = "TsProcessor.default.time.regex";
  public static final String TIME_REGEX = "TsProcessor.time.regex.";

  private Map<String, Pattern> datePatternMap;
  private Map<String, SimpleDateFormat> dateFormatMap;

  public TsProcessor() {
    datePatternMap = new HashMap<String, Pattern>();
    dateFormatMap = new HashMap<String, SimpleDateFormat>();
  }

  @Override
  protected void parse(String recordEntry,
      OutputCollector<ChukwaRecordKey, ChukwaRecord> output, Reporter reporter)
      throws Throwable {
    String dStr = null;
    try {
      SimpleDateFormat sdf = fetchDateFormat(chunk.getDataType());
      Pattern datePattern = fetchDateLocationPattern(chunk.getDataType());

      // fetch the part of the record that contains the date.
      if(datePattern != null) {
        Matcher m = datePattern.matcher(recordEntry);
        if (!m.matches() || m.groupCount() < 1) {
          throw new ParseException("Regex " + datePattern +
                  " couldn't extract date string from record: " + recordEntry, 0);
        }
        else {
          dStr = m.group(1);
        }
      }
      else {
        dStr = recordEntry;
      }

      Date d = sdf.parse(dStr);
      ChukwaRecord record = new ChukwaRecord();
      this.buildGenericRecord(record, recordEntry, d.getTime(), chunk
          .getDataType());
      output.collect(key, record);
    } catch (ParseException e) {
      log.warn("Unable to parse the date in DefaultProcessor [" + recordEntry
          + "], date string='" + dStr + "'", e);
      e.printStackTrace();
      throw e;
    } catch (IOException e) {
      log.warn("Unable to collect output in DefaultProcessor [" + recordEntry
          + "]", e);
      e.printStackTrace();
      throw e;
    }

  }
  
  /**
   * For a given dataType, returns the SimpeDateFormat to use.
   * @param dataType
   * @return
   */
  private SimpleDateFormat fetchDateFormat(String dataType) {
    if (dateFormatMap.get(dataType) != null) {
      return dateFormatMap.get(dataType);
    }

    Configuration jobConf = Demux.jobConf;
    String dateFormat = DEFAULT_DATE_FORMAT;

    if (jobConf != null) {
      dateFormat = jobConf.get("TsProcessor.default.time.format", dateFormat);
      dateFormat = jobConf.get("TsProcessor.time.format." + chunk.getDataType(),
                               dateFormat);
    }

    log.info("dataType: " + chunk.getDataType() + ", dateFormat="+ dateFormat);
    SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
    dateFormatMap.put(dataType, sdf);

    return sdf;
  }

  /**
   * For a given dataType, returns a Pattern that will produce the date portion
   * of the string.
   * @param dataType
   * @return
   */
  private Pattern fetchDateLocationPattern(String dataType) {
    if (datePatternMap.containsKey(dataType)) {
      return datePatternMap.get(dataType);
    }

    Configuration jobConf = Demux.jobConf;
    String datePattern = null;
    Pattern pattern = null;

    if (jobConf != null) {
      String timeRegexProperty = TIME_REGEX + chunk.getDataType();
      datePattern = jobConf.get(DEFAULT_TIME_REGEX, null);
      datePattern = jobConf.get(timeRegexProperty, datePattern);
      if (datePattern != null) {
        if (!RegexUtil.isRegex(datePattern, 1)) {
          log.warn("Error parsing '" + DEFAULT_TIME_REGEX + "' or '"
              + timeRegexProperty + "' properties as a regex: "
              + RegexUtil.regexError(datePattern, 1)
              + ". This date pattern will be skipped.");
          return null;
        }
        pattern = Pattern.compile(datePattern);
      }
    }

    datePatternMap.put(dataType, pattern);

    return pattern;
  }

}
