// Copyright (C) 2013 The Android Open Source Project
//
// 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.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.pgm.http.jetty;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import org.apache.log4j.Layout;
import org.apache.log4j.spi.LoggingEvent;

public final class HttpLogLayout extends Layout {
  private final SimpleDateFormat dateFormat;
  private long lastTimeMillis;
  private String lastTimeString;

  public HttpLogLayout() {
    final TimeZone tz = TimeZone.getDefault();
    dateFormat = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss Z");
    dateFormat.setTimeZone(tz);

    lastTimeMillis = System.currentTimeMillis();
    lastTimeString = dateFormat.format(new Date(lastTimeMillis));
  }

  @Override
  public String format(LoggingEvent event) {
    final StringBuilder buf = new StringBuilder(128);

    opt(buf, event, HttpLog.P_HOST);

    buf.append(' ');
    buf.append('[');
    buf.append(event.getThreadName());
    buf.append(']');

    buf.append(' ');
    buf.append('-'); // identd on client system (never requested)

    buf.append(' ');
    opt(buf, event, HttpLog.P_USER);

    buf.append(' ');
    buf.append('[');
    formatDate(event.getTimeStamp(), buf);
    buf.append(']');

    buf.append(' ');
    buf.append('"');
    buf.append(event.getMDC(HttpLog.P_METHOD));
    buf.append(' ');
    buf.append(event.getMDC(HttpLog.P_RESOURCE));
    buf.append(' ');
    buf.append(event.getMDC(HttpLog.P_PROTOCOL));
    buf.append('"');

    buf.append(' ');
    buf.append(event.getMDC(HttpLog.P_STATUS));

    buf.append(' ');
    opt(buf, event, HttpLog.P_CONTENT_LENGTH);

    buf.append(' ');
    opt(buf, event, HttpLog.P_LATENCY);

    buf.append(' ');
    dq_opt(buf, event, HttpLog.P_REFERER);

    buf.append(' ');
    dq_opt(buf, event, HttpLog.P_USER_AGENT);

    buf.append('\n');
    return buf.toString();
  }

  private void opt(StringBuilder buf, LoggingEvent event, String key) {
    String val = (String) event.getMDC(key);
    if (val == null) {
      buf.append('-');
    } else {
      buf.append(val);
    }
  }

  private void dq_opt(StringBuilder buf, LoggingEvent event, String key) {
    String val = (String) event.getMDC(key);
    if (val == null) {
      buf.append('-');
    } else {
      buf.append('"');
      buf.append(val);
      buf.append('"');
    }
  }

  private void formatDate(long now, StringBuilder sbuf) {
    final long rounded = now - (int) (now % 1000);
    if (rounded != lastTimeMillis) {
      synchronized (dateFormat) {
        lastTimeMillis = rounded;
        lastTimeString = dateFormat.format(new Date(lastTimeMillis));
        sbuf.append(lastTimeString);
      }
    } else {
      sbuf.append(lastTimeString);
    }
  }

  @Override
  public boolean ignoresThrowable() {
    return true;
  }

  @Override
  public void activateOptions() {}
}
