/*
 * 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.
 */

/* Portions copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software
 * License version 1.1, a copy of which has been included with this
 * distribution in the LICENSE.txt file.  */

package org.apache.hadoop.chukwa.inputtools.log4j;


import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Pattern;

import org.apache.hadoop.chukwa.datacollection.controller.ChukwaAgentController;
import org.apache.hadoop.chukwa.datacollection.controller.ClientFinalizer;
import org.apache.hadoop.chukwa.util.AdaptorNamingUtils;
import org.apache.hadoop.chukwa.util.RecordConstants;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.Logger;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LoggingEvent;

/**
    ChukwaDailyRollingFileAppender is a slightly modified version of
    DailyRollingFileAppender, with modified versions of its
    <code>subAppend()</code> and <code>rollOver()</code> functions. 
    We would have preferred to sub-class DailyRollingFileAppender but
    its authors clearly did not intend that to be a viable option since
    they made too much of the class private or package-private

    DailyRollingFileAppender extends {@link FileAppender} so that the
    underlying file is rolled over at a user chosen frequency.

    <p>The rolling schedule is specified by the <b>DatePattern</b>
    option. This pattern should follow the {@link SimpleDateFormat}
    conventions. In particular, you <em>must</em> escape literal text
    within a pair of single quotes. A formatted version of the date
    pattern is used as the suffix for the rolled file name.</p>

    <p>For example, if the <b>File</b> option is set to
    <code>/foo/bar.log</code> and the <b>DatePattern</b> set to
    <code>'.'yyyy-MM-dd</code>, on 2001-02-16 at midnight, the logging
    file <code>/foo/bar.log</code> will be copied to
    <code>/foo/bar.log.2001-02-16</code> and logging for 2001-02-17
    will continue in <code>/foo/bar.log</code> until it rolls over
    the next day.</p>

    <p>Is is possible to specify monthly, weekly, half-daily, daily,
    hourly, or minutely rollover schedules.</p>

    <table border="1" cellpadding="2" summary="">
    <tr>
    <th>DatePattern</th>
    <th>Rollover schedule</th>
    <th>Example</th></tr>

    <tr>
    <td><code>'.'yyyy-MM</code>
    <td>Rollover at the beginning of each month</td>

    <td>At midnight of May 31st, 2002 <code>/foo/bar.log</code> will be
    copied to <code>/foo/bar.log.2002-05</code>. Logging for the month
    of June will be output to <code>/foo/bar.log</code> until it is
    also rolled over the next month.</td></tr>

    <tr>
    <td><code>'.'yyyy-ww</code>

    <td>Rollover at the first day of each week. The first day of the
    week depends on the locale.</td>

    <td>Assuming the first day of the week is Sunday, on Saturday
    midnight, June 9th 2002, the file <i>/foo/bar.log</i> will be
    copied to <i>/foo/bar.log.2002-23</i>.  Logging for the 24th week
    of 2002 will be output to <code>/foo/bar.log</code> until it is
    rolled over the next week.</td></tr>

    <tr>
    <td><code>'.'yyyy-MM-dd</code>

    <td>Rollover at midnight each day.</td>

    <td>At midnight, on March 8th, 2002, <code>/foo/bar.log</code> will
    be copied to <code>/foo/bar.log.2002-03-08</code>. Logging for the
    9th day of March will be output to <code>/foo/bar.log</code> until
    it is rolled over the next day.</td></tr>

    <tr>
    <td><code>'.'yyyy-MM-dd-a</code>

    <td>Rollover at midnight and midday of each day.</td>

    <td>At noon, on March 9th, 2002, <code>/foo/bar.log</code> will be
    copied to <code>/foo/bar.log.2002-03-09-AM</code>. Logging for the
    afternoon of the 9th will be output to <code>/foo/bar.log</code>
    until it is rolled over at midnight.</td></tr>

    <tr>
    <td><code>'.'yyyy-MM-dd-HH</code>

    <td>Rollover at the top of every hour.</td>

    <td>At approximately 11:00.000 o'clock on March 9th, 2002,
    <code>/foo/bar.log</code> will be copied to
    <code>/foo/bar.log.2002-03-09-10</code>. Logging for the 11th hour
    of the 9th of March will be output to <code>/foo/bar.log</code>
    until it is rolled over at the beginning of the next hour.</td></tr>


    <tr>
    <td><code>'.'yyyy-MM-dd-HH-mm</code></td>

    <td>Rollover at the beginning of every minute.</td>

    <td>At approximately 11:23,000, on March 9th, 2001,
    <code>/foo/bar.log</code> will be copied to
    <code>/foo/bar.log.2001-03-09-10-22</code>. Logging for the minute
    of 11:23 (9th of March) will be output to
    <code>/foo/bar.log</code> until it is rolled over the next minute.</td></tr>
    </table>

    <p>Do not use the colon ":" character in anywhere in the
    <b>DatePattern</b> option. The text before the colon is interpeted
    as the protocol specificaion of a URL which is probably not what
    you want.</p> */

public class ChukwaDailyRollingFileAppender extends FileAppender {

  static Logger log = Logger.getLogger(ChukwaDailyRollingFileAppender.class);
  // The code assumes that the following constants are in a increasing
  // sequence.
  static final int TOP_OF_TROUBLE = -1;
  static final int TOP_OF_MINUTE = 0;
  static final int TOP_OF_HOUR = 1;
  static final int HALF_DAY = 2;
  static final int TOP_OF_DAY = 3;
  static final int TOP_OF_WEEK = 4;
  static final int TOP_OF_MONTH = 5;

  static final String adaptorType = ChukwaAgentController.CharFileTailUTF8NewLineEscaped;

  static final Object lock = new Object();
  static String lastRotation = "";

  /**
   * The date pattern. By default, the pattern is set to "'.'yyyy-MM-dd" meaning
   * daily rollover.
   */
  private String datePattern = "'.'yyyy-MM-dd";

  /**
   * The log file will be renamed to the value of the scheduledFilename variable
   * when the next interval is entered. For example, if the rollover period is
   * one hour, the log file will be renamed to the value of "scheduledFilename"
   * at the beginning of the next hour.
   * 
   * The precise time when a rollover occurs depends on logging activity.
   */
  private String scheduledFilename;

  /**
   * The next time we estimate a rollover should occur.
   */
  private long nextCheck = System.currentTimeMillis() - 1;

  /**
   * Regex to select log files to be deleted
   */
  private String cleanUpRegex = null;

  /**
   * Set the maximum number of backup files to keep around.
   */
  private int maxBackupIndex = 10;

  private ClientFinalizer clientFinalizer = null;
  
  boolean hasBeenActivated = false;
  Date now = new Date();

  SimpleDateFormat sdf;

  RollingCalendar rc = new RollingCalendar();

  int checkPeriod = TOP_OF_TROUBLE;

  ChukwaAgentController chukwaClient;
  boolean chukwaClientIsNull = true;
  static final Object chukwaLock = new Object();

  String chukwaClientHostname;
  int chukwaClientPortNum;
  long chukwaClientConnectNumRetry;
  long chukwaClientConnectRetryInterval;

  String recordType;

  // The gmtTimeZone is used only in computeCheckPeriod() method.
  static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");

  /**
   * The default constructor does nothing.
   * @throws IOException if constructor initialization error
   */
  public ChukwaDailyRollingFileAppender() throws IOException {
    super();
  }

/**
     Instantiate a <code>DailyRollingFileAppender</code> and open the
     file designated by <code>filename</code>. The opened filename will
     become the output destination for this appender.
 * @param layout is logging layout
 * @param filename is the filename to write logs
 * @param datePattern is the date pattern of log suffix
 * @throws IOException if constructor initialization error

   */
  public ChukwaDailyRollingFileAppender(Layout layout, String filename,
                                        String datePattern) throws IOException {
    super(layout, filename, true);
    System.out
        .println("Daily Rolling File Appender successfully registered file with agent: "
            + filename);
    this.datePattern = datePattern;
  }

  /**
   * The <b>DatePattern</b> takes a string in the same format as expected by
   * {@link SimpleDateFormat}. This options determines the rollover schedule.
   * @param pattern is date formatting pattern
   */
  public void setDatePattern(String pattern) {
    datePattern = pattern;
  }

  /** Returns the value of the <b>DatePattern</b> option. 
   * @return date pattern
   */
  public String getDatePattern() {
    return datePattern;
  }

  public String getRecordType() {
    if (recordType != null)
      return recordType;
    else
      return "unknown";
  }

  public void setRecordType(String recordType) {
    this.recordType = recordType;
  }

  public void activateOptions() {
    
    // Prevent early initialisation
    if (!hasBeenActivated)
    { return;}
    
    super.activateOptions();
    if (datePattern != null && fileName != null) {
      now.setTime(System.currentTimeMillis());
      sdf = new SimpleDateFormat(datePattern);
      int type = computeCheckPeriod();
      printPeriodicity(type);
      rc.setType(type);
      File file = new File(fileName);
      scheduledFilename = fileName + sdf.format(new Date(file.lastModified()));

    } else {
      LogLog
          .error("Either File or DatePattern options are not set for appender ["
              + name + "].");
    }
  }

  void printPeriodicity(int type) {
    switch (type) {
    case TOP_OF_MINUTE:
      LogLog.debug("Appender [" + name + "] to be rolled every minute.");
      break;
    case TOP_OF_HOUR:
      LogLog
          .debug("Appender [" + name + "] to be rolled on top of every hour.");
      break;
    case HALF_DAY:
      LogLog.debug("Appender [" + name
          + "] to be rolled at midday and midnight.");
      break;
    case TOP_OF_DAY:
      LogLog.debug("Appender [" + name + "] to be rolled at midnight.");
      break;
    case TOP_OF_WEEK:
      LogLog.debug("Appender [" + name + "] to be rolled at start of week.");
      break;
    case TOP_OF_MONTH:
      LogLog.debug("Appender [" + name
          + "] to be rolled at start of every month.");
      break;
    default:
      LogLog.warn("Unknown periodicity for appender [" + name + "].");
    }
  }

  // This method computes the roll over period by looping over the
  // periods, starting with the shortest, and stopping when the r0 is
  // different from from r1, where r0 is the epoch formatted according
  // the datePattern (supplied by the user) and r1 is the
  // epoch+nextMillis(i) formatted according to datePattern. All date
  // formatting is done in GMT and not local format because the test
  // logic is based on comparisons relative to 1970-01-01 00:00:00
  // GMT (the epoch).

  int computeCheckPeriod() {
    RollingCalendar rollingCalendar = new RollingCalendar(gmtTimeZone,
        Locale.ENGLISH);
    // set sate to 1970-01-01 00:00:00 GMT
    Date epoch = new Date(0);
    if (datePattern != null) {
      for (int i = TOP_OF_MINUTE; i <= TOP_OF_MONTH; i++) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern);
        simpleDateFormat.setTimeZone(gmtTimeZone); // do all date formatting in
                                                   // GMT
        String r0 = simpleDateFormat.format(epoch);
        rollingCalendar.setType(i);
        Date next = new Date(rollingCalendar.getNextCheckMillis(epoch));
        String r1 = simpleDateFormat.format(next);
        // System.out.println("Type = "+i+", r0 = "+r0+", r1 = "+r1);
        if (r0 != null && r1 != null && !r0.equals(r1)) {
          return i;
        }
      }
    }
    return TOP_OF_TROUBLE; // Deliberately head for trouble...
  }

  /**
   * Rollover the current file to a new file.
   */
  void rollOver() throws IOException {

    /* Compute filename, but only if datePattern is specified */
    if (datePattern == null) {
      errorHandler.error("Missing DatePattern option in rollOver().");
      return;
    }

    String datedFilename = fileName + sdf.format(now);
    // It is too early to roll over because we are still within the
    // bounds of the current interval. Rollover will occur once the
    // next interval is reached.
    if (scheduledFilename.equals(datedFilename)) {
      return;
    }

    // close current file, and rename it to datedFilename
    this.closeFile();

    File target = new File(scheduledFilename);
    if (target.exists()) {
      if(!target.delete()) {
        LogLog.warn("Unable to remove: "+target.getAbsolutePath());
      };
    }

    File file = new File(fileName);

    boolean result = file.renameTo(target);
    if (result) {
      LogLog.debug(fileName + " -> " + scheduledFilename);
    } else {
      LogLog.error("Failed to rename [" + fileName + "] to ["
          + scheduledFilename + "].");
    }

    try {
      // This will also close the file. This is OK since multiple
      // close operations are safe.
      this.setFile(fileName, false, this.bufferedIO, this.bufferSize);
    } catch (IOException e) {
      errorHandler.error("setFile(" + fileName + ", false) call failed.");
    }
    scheduledFilename = datedFilename;
    cleanUp();
  }

  public synchronized String getCleanUpRegex() {
    return cleanUpRegex;
  }

  protected synchronized void setCleanUpRegex(String cleanUpRegex) {
    this.cleanUpRegex = cleanUpRegex;
  }

  public int getMaxBackupIndex() {
    return maxBackupIndex;
  }

  public void setMaxBackupIndex(int maxBackupIndex) {
    this.maxBackupIndex = maxBackupIndex;
  }

  protected synchronized void cleanUp() {
    String regex = "";
    try {
      File actualFile = new File(fileName);

      String directoryName = actualFile.getParent();
      String actualFileName = actualFile.getName();
      File dirList = new File(directoryName);

      if (cleanUpRegex == null || !cleanUpRegex.contains("$fileName")) {
        LogLog
            .error("cleanUpRegex == null || !cleanUpRegex.contains(\"$fileName\")");
        return;
      }
      regex = cleanUpRegex.replace("$fileName", actualFileName);
      String[] dirFiles = dirList.list(new LogFilter(actualFileName, regex));

      List<String> files = new ArrayList<String>();
      if(dirFiles!=null) {
        for (String file : dirFiles) {
          files.add(file);
        }
      }
      Collections.sort(files);

      while (files.size() > maxBackupIndex) {
        String file = files.remove(0);
        File f = new File(directoryName + "/" + file);
        if(!f.delete()) {
          LogLog.warn("Cannot remove: " + file);
        }
      }
    } catch (Exception e) {
      errorHandler
          .error("cleanUp(" + fileName + "," + regex + ") call failed.");
    }
  }

  private static class LogFilter implements FilenameFilter {
    private Pattern p = null;
    private String logFile = null;

    public LogFilter(String logFile, String regex) {
      this.logFile = logFile;
      p = Pattern.compile(regex);
    }

    @Override
    public boolean accept(File dir, String name) {
      // ignore current log file
      if (name.intern() == this.logFile.intern()) {
        return false;
      }
      // ignore file without the same prefix
      if (!name.startsWith(logFile)) {
        return false;
      }
      return p.matcher(name).find();
    }
  }

  /**
   * Fix for late-initialisation
   */
  @Override
  protected boolean checkEntryConditions() {
    synchronized(chukwaLock) {
      if (!hasBeenActivated) {
        hasBeenActivated = true;
        activateOptions();
      }
    }
    return super.checkEntryConditions();
  }

  /**
   * This method differentiates DailyRollingFileAppender from its super class.
   * 
   * <p>Before actually logging, this method will check whether it is time to do
   * a rollover. If it is, it will schedule the next rollover time and then
   * rollover.
   * */
  protected void subAppend(LoggingEvent event) {
    try {
      // we set up the chukwa adaptor here because this is the first
      // point which is called after all setters have been called with
      // their values from the log4j.properties file, in particular we
      // needed to give setCukwaClientPortNum() and -Hostname() a shot

      // Make sure only one thread can do this
      // and use the boolean to avoid the first level locking
      if (chukwaClientIsNull) {
        synchronized (chukwaLock) {

          String log4jFileName = getFile(); 
          String recordType = getRecordType();

          long currentLength = 0L;
          try {
            File fooLog = new File(log4jFileName);
            log4jFileName = fooLog.getAbsolutePath();
            currentLength = fooLog.length();
          } catch (Throwable e) {
            log.warn("Exception while trying to get current file size for " + log4jFileName);
            currentLength = 0L;
          }

          if (chukwaClient == null) {
            if (getChukwaClientHostname() != null
                && getChukwaClientPortNum() != 0) {
              chukwaClient = new ChukwaAgentController(
                  getChukwaClientHostname(), getChukwaClientPortNum());
              log.debug("setup adaptor with hostname "
                  + getChukwaClientHostname() + " and portnum "
                  + getChukwaClientPortNum());
            } else {
              chukwaClient = new ChukwaAgentController();
              log
              .debug("setup adaptor with no args, which means it used its defaults");
            }

            chukwaClientIsNull = false;

            // Watchdog is watching for ChukwaAgent only once every 5 minutes,
            // so there's no point in retrying more than once every 5 mins.
            // In practice, if the watchdog is not able to automatically restart
            // the agent, it will take more than 20 minutes to get Ops to
            // restart it.
            // Also its a good to limit the number of communications between
            // Hadoop and Chukwa, that's why 30 minutes.
            long retryInterval = chukwaClientConnectRetryInterval;
            if (retryInterval == 0) {
              retryInterval = 1000 * 60 * 30;
            }
            long numRetries = chukwaClientConnectNumRetry;
            if (numRetries == 0) {
              numRetries = 48;
            }

            String name = AdaptorNamingUtils.synthesizeAdaptorID
              (ChukwaAgentController.CharFileTailUTF8NewLineEscaped, recordType, log4jFileName);
            
            String adaptorID = chukwaClient.addByName(name, ChukwaAgentController.CharFileTailUTF8NewLineEscaped,
                recordType,currentLength + " " + log4jFileName, currentLength,
                numRetries, retryInterval);

            // Setup a shutdownHook for the controller
            clientFinalizer = new ClientFinalizer(chukwaClient);
            Runtime.getRuntime().addShutdownHook(clientFinalizer);

            if (adaptorID != null) {
              log.debug("Added file tailing adaptor to chukwa agent for file "
                  + log4jFileName + ", adaptorId:" + adaptorID 
                  + " using this recordType :" + recordType 
                  + ", starting at offset:" + currentLength);
            } else {
              log.debug("Chukwa adaptor not added, addFile(" + log4jFileName
                  + ") returned, current offset: " + currentLength);
            }

          }
        }
      }

      long n = System.currentTimeMillis();
      if (n >= nextCheck) {
        now.setTime(n);
        nextCheck = rc.getNextCheckMillis(now);
        try {
          rollOver();
        } catch (IOException ioe) {
          LogLog.error("rollOver() failed.", ioe);
        }
      }

      boolean written = false;
      if(layout.ignoresThrowable()) {
        String[] s = event.getThrowableStrRep();
        if (s != null) {
          int len = s.length;
          StringBuilder sb = new StringBuilder();
          sb.append(this.layout.format(event));
          for(int i = 0; i < len; i++) {
            sb.append(s[i]).append("\n");
          }
          //escape the newlines from record bodies, exception and then write this record to the log file
          written = true;
          this.qw.write(RecordConstants.escapeAllButLastRecordSeparator("\n",sb.toString()));
        } 
      }
       
      if (!written) {
        //escape the newlines from record bodies and then write this record to the log file
        this.qw.write(RecordConstants.escapeAllButLastRecordSeparator("\n",this.layout.format(event)));
      }
      
      if (this.immediateFlush) {
        this.qw.flush();
      }
    } catch (Throwable e) {
      System.err.println("Exception in ChukwaRollingAppender: "
          + e.getMessage());
      e.printStackTrace();
    }

  }

  public String getChukwaClientHostname() {
    return chukwaClientHostname;
  }

  public void setChukwaClientHostname(String chukwaClientHostname) {
    this.chukwaClientHostname = chukwaClientHostname;
  }

  public int getChukwaClientPortNum() {
    return chukwaClientPortNum;
  }

  public void setChukwaClientPortNum(int chukwaClientPortNum) {
    this.chukwaClientPortNum = chukwaClientPortNum;
  }

  public void setChukwaClientConnectNumRetry(int i) {
    this.chukwaClientConnectNumRetry = i;
  }

  public void setChukwaClientConnectRetryInterval(long i) {
    this.chukwaClientConnectRetryInterval = i;
  }

}


/**
 * RollingCalendar is a helper class to DailyRollingFileAppender. Given a
 * periodicity type and the current time, it computes the start of the next
 * interval.
 * */
class RollingCalendar extends GregorianCalendar {

  /**
	 * 
	 */
  private static final long serialVersionUID = 2153481574198792767L;
  int type = ChukwaDailyRollingFileAppender.TOP_OF_TROUBLE;

  RollingCalendar() {
    super();
  }

  RollingCalendar(TimeZone tz, Locale locale) {
    super(tz, locale);
  }

  void setType(int type) {
    this.type = type;
  }

  public long getNextCheckMillis(Date now) {
    return getNextCheckDate(now).getTime();
  }

  public Date getNextCheckDate(Date now) {
    this.setTime(now);

    switch (type) {
    case ChukwaDailyRollingFileAppender.TOP_OF_MINUTE:
      this.set(Calendar.SECOND, 0);
      this.set(Calendar.MILLISECOND, 0);
      this.add(Calendar.MINUTE, 1);
      break;
    case ChukwaDailyRollingFileAppender.TOP_OF_HOUR:
      this.set(Calendar.MINUTE, 0);
      this.set(Calendar.SECOND, 0);
      this.set(Calendar.MILLISECOND, 0);
      this.add(Calendar.HOUR_OF_DAY, 1);
      break;
    case ChukwaDailyRollingFileAppender.HALF_DAY:
      this.set(Calendar.MINUTE, 0);
      this.set(Calendar.SECOND, 0);
      this.set(Calendar.MILLISECOND, 0);
      int hour = get(Calendar.HOUR_OF_DAY);
      if (hour < 12) {
        this.set(Calendar.HOUR_OF_DAY, 12);
      } else {
        this.set(Calendar.HOUR_OF_DAY, 0);
        this.add(Calendar.DAY_OF_MONTH, 1);
      }
      break;
    case ChukwaDailyRollingFileAppender.TOP_OF_DAY:
      this.set(Calendar.HOUR_OF_DAY, 0);
      this.set(Calendar.MINUTE, 0);
      this.set(Calendar.SECOND, 0);
      this.set(Calendar.MILLISECOND, 0);
      this.add(Calendar.DATE, 1);
      break;
    case ChukwaDailyRollingFileAppender.TOP_OF_WEEK:
      this.set(Calendar.DAY_OF_WEEK, getFirstDayOfWeek());
      this.set(Calendar.HOUR_OF_DAY, 0);
      this.set(Calendar.SECOND, 0);
      this.set(Calendar.MILLISECOND, 0);
      this.add(Calendar.WEEK_OF_YEAR, 1);
      break;
    case ChukwaDailyRollingFileAppender.TOP_OF_MONTH:
      this.set(Calendar.DATE, 1);
      this.set(Calendar.HOUR_OF_DAY, 0);
      this.set(Calendar.SECOND, 0);
      this.set(Calendar.MILLISECOND, 0);
      this.add(Calendar.MONTH, 1);
      break;
    default:
      throw new IllegalStateException("Unknown periodicity type.");
    }
    return getTime();
  }
  
  @Override
  public boolean equals(Object o) {
    return super.equals(o);
  }
  
  @Override
  public int hashCode() {
    return super.hashCode();
  }
}
