/*
 * 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.logging.log4j.core.pattern;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.TimeZone;

import org.apache.logging.log4j.core.AbstractLogEvent;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.time.Instant;
import org.apache.logging.log4j.core.time.MutableInstant;
import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat;
import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat.FixedTimeZoneFormat;
import org.apache.logging.log4j.core.util.Constants;
import org.apache.logging.log4j.util.Strings;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class DatePatternConverterTest {

    private class MyLogEvent extends AbstractLogEvent {
        private static final long serialVersionUID = 0;

        @Override
        public Instant getInstant() {
            MutableInstant result = new MutableInstant();
            result.initFromEpochMilli(getTimeMillis(), 123456);
            return result;
        }

        @Override
        public long getTimeMillis() {
            final Calendar cal = Calendar.getInstance();
            cal.set(2011, Calendar.DECEMBER, 30, 10, 56, 35);
            cal.set(Calendar.MILLISECOND, 987);
            return cal.getTimeInMillis();
        }
    }

    /**
     * SimpleTimePattern for DEFAULT.
     */
    private static final String DEFAULT_PATTERN = FixedDateFormat.FixedFormat.DEFAULT.getPattern();

    /**
     * ISO8601 string literal.
     */
    private static final String ISO8601 = FixedDateFormat.FixedFormat.ISO8601.name();

    /**
     * ISO8601_OFFSE_DATE_TIME_XX string literal.
     */
    private static final String ISO8601_OFFSE_DATE_TIME_HHMM = FixedDateFormat.FixedFormat.ISO8601_OFFSET_DATE_TIME_HHMM
            .name();

    /**
     * ISO8601_OFFSET_DATE_TIME_XXX string literal.
     */
    private static final String ISO8601_OFFSET_DATE_TIME_HHCMM = FixedDateFormat.FixedFormat.ISO8601_OFFSET_DATE_TIME_HHCMM
            .name();

    private static final String[] ISO8601_FORMAT_OPTIONS = { ISO8601 };

    @Parameterized.Parameters(name = "threadLocalEnabled={0}")
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][]{{Boolean.TRUE}, {Boolean.FALSE}});
    }

    public DatePatternConverterTest(final Boolean threadLocalEnabled) throws Exception {
        // Setting the system property does not work: the Constant field has already been initialized...
        //System.setProperty("log4j2.enable.threadlocals", threadLocalEnabled.toString());

        final Field field = Constants.class.getDeclaredField("ENABLE_THREADLOCALS");
        field.setAccessible(true); // make non-private

        final Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); // make non-final

        field.setBoolean(null, threadLocalEnabled.booleanValue());
    }

    private Date date(final int year, final int month, final int date) {
        final Calendar cal = Calendar.getInstance();
        cal.set(year, month, date, 14, 15, 16);
        cal.set(Calendar.MILLISECOND, 123);
        return cal.getTime();
    }

    private String precisePattern(final String pattern, int precision) {
        String search = "SSS";
        int foundIndex = pattern.indexOf(search);
        final String seconds = pattern.substring(0, foundIndex);
        final String remainder = pattern.substring(foundIndex + search.length());
        return seconds + "nnnnnnnnn".substring(0, precision) + remainder;
    }

    @Test
    public void testFormatDateStringBuilderDefaultPattern() {
        final DatePatternConverter converter = DatePatternConverter.newInstance(null);
        final StringBuilder sb = new StringBuilder();
        converter.format(date(2001, 1, 1), sb);

        final String expected = "2001-02-01 14:15:16,123";
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testFormatDateStringBuilderIso8601() {
        final DatePatternConverter converter = DatePatternConverter.newInstance(ISO8601_FORMAT_OPTIONS);
        final StringBuilder sb = new StringBuilder();
        converter.format(date(2001, 1, 1), sb);

        final String expected = "2001-02-01T14:15:16,123";
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testFormatDateStringBuilderIso8601BasicWithPeriod() {
        final String[] pattern = {FixedDateFormat.FixedFormat.ISO8601_BASIC_PERIOD.name()};
        final DatePatternConverter converter = DatePatternConverter.newInstance(pattern);
        final StringBuilder sb = new StringBuilder();
        converter.format(date(2001, 1, 1), sb);

        final String expected = "20010201T141516.123";
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testFormatDateStringBuilderIso8601WithPeriod() {
        final String[] pattern = {FixedDateFormat.FixedFormat.ISO8601_PERIOD.name()};
        final DatePatternConverter converter = DatePatternConverter.newInstance(pattern);
        final StringBuilder sb = new StringBuilder();
        converter.format(date(2001, 1, 1), sb);

        final String expected = "2001-02-01T14:15:16.123";
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testFormatDateStringBuilderIso8601WithPeriodMicroseconds() {
        final String[] pattern = {FixedDateFormat.FixedFormat.ISO8601_PERIOD_MICROS.name(), "Z"};
        final DatePatternConverter converter = DatePatternConverter.newInstance(pattern);
        final StringBuilder sb = new StringBuilder();
        MutableInstant instant = new MutableInstant();
        instant.initFromEpochMilli(
                1577225134559L,
                // One microsecond
                1000);
        converter.format(instant, sb);

        final String expected = "2019-12-24T22:05:34.559001";
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testFormatDateStringBuilderOriginalPattern() {
        final String[] pattern = {"yyyy/MM/dd HH-mm-ss.SSS"};
        final DatePatternConverter converter = DatePatternConverter.newInstance(pattern);
        final StringBuilder sb = new StringBuilder();
        converter.format(date(2001, 1, 1), sb);

        final String expected = "2001/02/01 14-15-16.123";
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testFormatLogEventStringBuilderDefaultPattern() {
        final LogEvent event = new MyLogEvent();
        final DatePatternConverter converter = DatePatternConverter.newInstance(null);
        final StringBuilder sb = new StringBuilder();
        converter.format(event, sb);

        final String expected = "2011-12-30 10:56:35,987";
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testFormatLogEventStringBuilderIso8601() {
        final LogEvent event = new MyLogEvent();
        final DatePatternConverter converter = DatePatternConverter.newInstance(ISO8601_FORMAT_OPTIONS);
        final StringBuilder sb = new StringBuilder();
        converter.format(event, sb);

        final String expected = "2011-12-30T10:56:35,987";
        assertEquals(expected, sb.toString());
    }
    
    @Test
    public void testFormatLogEventStringBuilderIso8601TimezoneJST() {
        final LogEvent event = new MyLogEvent();
        final String[] optionsWithTimezone = {ISO8601, "JST"};
        final DatePatternConverter converter = DatePatternConverter.newInstance(optionsWithTimezone);
        final StringBuilder sb = new StringBuilder();
        converter.format(event, sb);

        // JST=Japan Standard Time: UTC+9:00
        final TimeZone tz = TimeZone.getTimeZone("JST");
        final SimpleDateFormat sdf = new SimpleDateFormat(converter.getPattern());
        sdf.setTimeZone(tz);
        final long adjusted = event.getTimeMillis() + tz.getDSTSavings();
        final String expected = sdf.format(new Date(adjusted));
        // final String expected = "2011-12-30T18:56:35,987"; // in CET (Central Eastern Time: Amsterdam)
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testFormatLogEventStringBuilderIso8601TimezoneOffsetHHCMM() {
        final LogEvent event = new MyLogEvent();
        final String[] optionsWithTimezone = { ISO8601_OFFSET_DATE_TIME_HHCMM };
        final DatePatternConverter converter = DatePatternConverter.newInstance(optionsWithTimezone);
        final StringBuilder sb = new StringBuilder();
        converter.format(event, sb);

        final SimpleDateFormat sdf = new SimpleDateFormat(converter.getPattern());
        final String format = sdf.format(new Date(event.getTimeMillis()));
        final String expected = format.endsWith("Z") ? format.substring(0, format.length() - 1) + "+00:00" : format;
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testFormatLogEventStringBuilderIso8601TimezoneOffsetHHMM() {
        final LogEvent event = new MyLogEvent();
        final String[] optionsWithTimezone = { ISO8601_OFFSE_DATE_TIME_HHMM };
        final DatePatternConverter converter = DatePatternConverter.newInstance(optionsWithTimezone);
        final StringBuilder sb = new StringBuilder();
        converter.format(event, sb);

        final SimpleDateFormat sdf = new SimpleDateFormat(converter.getPattern());
        final String format = sdf.format(new Date(event.getTimeMillis()));
        final String expected = format.endsWith("Z") ? format.substring(0, format.length() - 1) + "+0000" : format;
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testFormatLogEventStringBuilderIso8601TimezoneUTC() {
        final LogEvent event = new MyLogEvent();
        final DatePatternConverter converter = DatePatternConverter.newInstance(new String[] {"ISO8601", "UTC"});
        final StringBuilder sb = new StringBuilder();
        converter.format(event, sb);

        final TimeZone tz = TimeZone.getTimeZone("UTC");
        final SimpleDateFormat sdf = new SimpleDateFormat(converter.getPattern());
        sdf.setTimeZone(tz);
        final long adjusted = event.getTimeMillis() + tz.getDSTSavings();
        final String expected = sdf.format(new Date(adjusted));
        // final String expected = "2011-12-30T09:56:35,987";
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testFormatLogEventStringBuilderIso8601TimezoneZ() {
        final LogEvent event = new MyLogEvent();
        final String[] optionsWithTimezone = { ISO8601, "Z" };
        final DatePatternConverter converter = DatePatternConverter.newInstance(optionsWithTimezone);
        final StringBuilder sb = new StringBuilder();
        converter.format(event, sb);

        final TimeZone tz = TimeZone.getTimeZone("UTC");
        final SimpleDateFormat sdf = new SimpleDateFormat(converter.getPattern());
        sdf.setTimeZone(tz);
        final long adjusted = event.getTimeMillis() + tz.getDSTSavings();
        final String expected = sdf.format(new Date(adjusted));
        // final String expected = "2011-12-30T17:56:35,987"; // in UTC
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testFormatObjectStringBuilderDefaultPattern() {
        final DatePatternConverter converter = DatePatternConverter.newInstance(null);
        final StringBuilder sb = new StringBuilder();
        converter.format("nondate", sb);

        final String expected = ""; // only process dates
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testFormatStringBuilderObjectArrayDefaultPattern() {
        final DatePatternConverter converter = DatePatternConverter.newInstance(null);
        final StringBuilder sb = new StringBuilder();
        converter.format(sb, date(2001, 1, 1), date(2002, 2, 2), date(2003, 3, 3));

        final String expected = "2001-02-01 14:15:16,123"; // only process first date
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testFormatStringBuilderObjectArrayIso8601() {
        final DatePatternConverter converter = DatePatternConverter.newInstance(ISO8601_FORMAT_OPTIONS);
        final StringBuilder sb = new StringBuilder();
        converter.format(sb, date(2001, 1, 1), date(2002, 2, 2), date(2003, 3, 3));

        final String expected = "2001-02-01T14:15:16,123"; // only process first date
        assertEquals(expected, sb.toString());
    }

    @Test
    public void testGetPatternReturnsDefaultForEmptyOptionsArray() {
        assertEquals(DEFAULT_PATTERN, DatePatternConverter.newInstance(new String[0]).getPattern());
    }

    @Test
    public void testGetPatternReturnsDefaultForInvalidPattern() {
        final String[] invalid = {"ABC I am not a valid date pattern"};
        assertEquals(DEFAULT_PATTERN, DatePatternConverter.newInstance(invalid).getPattern());
    }

    @Test
    public void testGetPatternReturnsDefaultForNullOptions() {
        assertEquals(DEFAULT_PATTERN, DatePatternConverter.newInstance(null).getPattern());
    }

    @Test
    public void testGetPatternReturnsDefaultForSingleNullElementOptionsArray() {
        assertEquals(DEFAULT_PATTERN, DatePatternConverter.newInstance(new String[1]).getPattern());
    }

    @Test
    public void testGetPatternReturnsDefaultForTwoNullElementsOptionsArray() {
        assertEquals(DEFAULT_PATTERN, DatePatternConverter.newInstance(new String[2]).getPattern());
    }

    @Test
    public void testGetPatternReturnsNullForUnix() {
        final String[] options = {"UNIX"};
        assertNull(DatePatternConverter.newInstance(options).getPattern());
    }

    @Test
    public void testGetPatternReturnsNullForUnixMillis() {
        final String[] options = {"UNIX_MILLIS"};
        assertNull(DatePatternConverter.newInstance(options).getPattern());
    }

    @Test
    public void testInvalidLongPatternIgnoresExcessiveDigits() {
        final StringBuilder preciseBuilder = new StringBuilder();
        final StringBuilder milliBuilder = new StringBuilder();
        final LogEvent event = new MyLogEvent();

        for (final FixedDateFormat.FixedFormat format : FixedDateFormat.FixedFormat.values()) {
            String pattern = format.getPattern();
            final String search = "SSS";
            final int foundIndex = pattern.indexOf(search);
            if (pattern.endsWith("n") || pattern.matches(".+n+X*") || pattern.matches(".+n+Z*")) {
                // ignore patterns that already have precise time formats
                // ignore patterns that do not use seconds.
                continue;
            }
            preciseBuilder.setLength(0);
            milliBuilder.setLength(0);

            final DatePatternConverter preciseConverter;
            final String precisePattern;
            if (foundIndex < 0) {
                precisePattern = pattern;
                preciseConverter = DatePatternConverter.newInstance(new String[] { precisePattern });
            } else {
                final String subPattern = pattern.substring(0, foundIndex);
                final String remainder = pattern.substring(foundIndex + search.length());
                precisePattern = subPattern + "nnnnnnnnn" + "n" + remainder; // nanos too long
                preciseConverter = DatePatternConverter.newInstance(new String[] { precisePattern });
            }
            preciseConverter.format(event, preciseBuilder);

            final String[] milliOptions = { pattern };
            DatePatternConverter.newInstance(milliOptions).format(event, milliBuilder);
            FixedTimeZoneFormat timeZoneFormat = format.getTimeZoneFormat();
            final int truncateLen = 3 + (timeZoneFormat != null ? timeZoneFormat.getLength() : 0);
            final String tz = timeZoneFormat != null
                    ? milliBuilder.substring(milliBuilder.length() - timeZoneFormat.getLength(), milliBuilder.length())
                    : Strings.EMPTY;
            milliBuilder.setLength(milliBuilder.length() - truncateLen); // truncate millis
            if (foundIndex >= 0) {
                milliBuilder.append("987123456");
            }
            final String expected = milliBuilder.append(tz).toString();

            assertEquals("format = " + format + ", pattern = " + pattern + ", precisePattern = " + precisePattern,
                    expected, preciseBuilder.toString());
            // System.out.println(preciseOptions[0] + ": " + precise);
        }
    }

    @Test
    public void testNewInstanceAllowsNullParameter() {
        DatePatternConverter.newInstance(null); // no errors
    }

    // test with all formats from one 'n' (100s of millis) to 'nnnnnnnnn' (nanosecond precision)
    @Test
    public void testPredefinedFormatWithAnyValidNanoPrecision() {
        final StringBuilder preciseBuilder = new StringBuilder();
        final StringBuilder milliBuilder = new StringBuilder();
        final LogEvent event = new MyLogEvent();

        for (final String timeZone : new String[] { "PDT", null }) { // Pacific Daylight Time=UTC-8:00
            for (final FixedDateFormat.FixedFormat format : FixedDateFormat.FixedFormat.values()) {
                for (int i = 1; i <= 9; i++) {
                    final String pattern = format.getPattern();
                    if (pattern.endsWith("n") || pattern.matches(".+n+X*") || pattern.matches(".+n+Z*")
                            || pattern.indexOf("SSS") < 0) {
                        // ignore patterns that already have precise time formats
                        // ignore patterns that do not use seconds.
                        continue;
                    }
                    preciseBuilder.setLength(0);
                    milliBuilder.setLength(0);

                    final String precisePattern = precisePattern(pattern, i);
                    final String[] preciseOptions = { precisePattern, timeZone };
                    final DatePatternConverter preciseConverter = DatePatternConverter.newInstance(preciseOptions);
                    preciseConverter.format(event, preciseBuilder);

                    final String[] milliOptions = { pattern, timeZone };
                    DatePatternConverter.newInstance(milliOptions).format(event, milliBuilder);
                    FixedTimeZoneFormat timeZoneFormat = format.getTimeZoneFormat();
                    final int truncateLen = 3 + (timeZoneFormat != null ? timeZoneFormat.getLength() : 0);
                    final String tz = timeZoneFormat != null
                            ? milliBuilder.substring(milliBuilder.length() - timeZoneFormat.getLength(),
                                    milliBuilder.length())
                            : Strings.EMPTY;
                    milliBuilder.setLength(milliBuilder.length() - truncateLen); // truncate millis
                    final String expected = milliBuilder.append("987123456".substring(0, i)).append(tz).toString();

                    assertEquals(
                            "format = " + format + ", pattern = " + pattern + ", precisePattern = " + precisePattern,
                            expected, preciseBuilder.toString());
                    // System.out.println(preciseOptions[0] + ": " + precise);
                }
            }
        }
    }

    @Test
    public void testPredefinedFormatWithoutTimezone() {
        for (final FixedDateFormat.FixedFormat format : FixedDateFormat.FixedFormat.values()) {
            final String[] options = {format.name()};
            final DatePatternConverter converter = DatePatternConverter.newInstance(options);
            assertEquals(format.getPattern(), converter.getPattern());
        }
    }

    @Test
    public void testPredefinedFormatWithTimezone() {
        for (final FixedDateFormat.FixedFormat format : FixedDateFormat.FixedFormat.values()) {
            final String[] options = {format.name(), "PDT"}; // Pacific Daylight Time=UTC-8:00
            final DatePatternConverter converter = DatePatternConverter.newInstance(options);
            assertEquals(format.getPattern(), converter.getPattern());
        }
    }

}
