/*
 * Copyright (c) 2012-2014 Spotify AB
 *
 * 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 de.rwth.idsg.bikeman.utils;

import ch.qos.logback.classic.pattern.SyslogStartConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.util.LevelToSyslogSeverity;
import ch.qos.logback.core.net.SyslogAppenderBase;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;

import java.io.IOException;

/**
 * Taken from: https://github.com/spotify/logging-java/tree/master/src/main/java/com/spotify/logging/logback
 *
 * Modified to use Joda-Time
 *
 * A {@link SyslogStartConverter} with millisecond timestamp
 * precision.
 */
public class MillisecondPrecisionSyslogStartConverter extends SyslogStartConverter {

    private long lastTimestamp = -1;
    private DateTimeFormatter isoFormatter;
    private String localHostName;
    private int facility;

    public void start() {
        int errorCount = 0;

        final String facilityStr = getFirstOption();
        if (facilityStr == null) {
            addError("was expecting a facility string as an option");
            return;
        }

        facility = SyslogAppenderBase.facilityStringToint(facilityStr);

        localHostName = getLocalHostname();
        try {
            isoFormatter = ISODateTimeFormat.dateHourMinuteSecondMillis();
        } catch (Exception e) {
            addError("Could not instantiate Joda DateTimeFormatter", e);
            errorCount++;
        }

        if (errorCount == 0) {
            super.start();
        }
    }

    public String convert(final ILoggingEvent event) {
        final StringBuilder sb = new StringBuilder();

        final int pri = facility + LevelToSyslogSeverity.convert(event);

        sb.append("<");
        sb.append(pri);
        sb.append(">");
        computeTimeStampString(sb, event.getTimeStamp());
        sb.append(' ');
        sb.append(localHostName);
        sb.append(' ');

        return sb.toString();
    }

    void computeTimeStampString(StringBuilder sb, final long now) {
        synchronized (this) {
            if (now != lastTimestamp) {
                lastTimestamp = now;
                try {
                    isoFormatter.printTo(sb, now);
                } catch (IOException e) {
                    addError("Failed to convert timestamp to string", e);
                }
            }
        }
    }
}



@@ -927,19 +927,16 @@
 .format.
-ISO
 DateTime
@@ -941,16 +941,26 @@
 meFormat
+terBuilder
 ;%0A%0Aimpor
@@ -1127,16 +1127,87 @@
 oda-Time
+ and ISO-8601 in order to meet the syslog timestamp format expectations
 %0A *%0A * A
@@ -1371,45 +1371,8 @@
  %7B%0A%0A
-    private long lastTimestamp = -1;%0A
     
@@ -1874,19 +1874,20 @@
 atter = 
-ISO
+new 
 DateTime
@@ -1896,39 +1896,169 @@
 rmat
-.dateHourMinuteSecondMillis
+terBuilder()%0A                .appendPattern(%22yyyy-MM-dd'T'HH:mm:ss.SSS%22)%0A                .appendTimeZoneOffset(%22Z%22, true, 2, 4)%0A                .toFormatter
 ();%0A
+%0A
     
@@ -2806,89 +2806,8 @@
 ) %7B%0A
-            if (now != lastTimestamp) %7B%0A                lastTimestamp = now;%0A    
     
@@ -2828,36 +2828,32 @@
                 
-   
- 
 isoFormatter.pri
@@ -2875,28 +2875,24 @@
             
-    
 %7D catch (IOE
@@ -2913,36 +2913,32 @@
                 
-  
-  
 addError(%22Failed
@@ -2979,26 +2979,8 @@
 e);%0A
-                %7D%0A
     

format corrections and removed the caching of the produced timestamp string