/*
 * 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.maven.scm;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;

import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

/**
 * Tests for the {@link ChangeSet}class
 *
 * @author dion
 *
 */
public class ChangeSetTest {
    /**
     * the {@link ChangeSet} used for testing
     */
    private ChangeSet instance;

    /**
     * Initialize per test data
     */
    @Before
    public void setUp() {
        instance = createInstance();
    }

    private static ChangeSet createInstance() {
        ChangeSet instance = new ChangeSet();
        instance.setAuthor("dion");
        instance.setComment("comment");
        instance.setDate("2002/04/01 00:00:00");
        instance.setTags(Arrays.asList("v3.14", "v2<bla>.7]]1828", "<![CDATA[NastyTag"));
        return instance;
    }

    /**
     * Test of addFile methods: using ChangeFile
     */
    @Test
    public void testAddFileWithFile() {
        ChangeFile file = new ChangeFile("maven:dummy");
        instance.addFile(file);
        assertTrue("File name not found in list", instance.toString().indexOf("maven:dummy") != -1);

        assertTrue(instance.containsFilename("maven:"));
        assertTrue(instance.containsFilename(":dummy"));
        assertTrue(instance.containsFilename(":"));
        assertTrue(instance.containsFilename("maven:dummy"));
        assertFalse(instance.containsFilename("dammy"));
    }

    /**
     * Test of toString method
     */
    @Test
    public void testToString() {
        // dion, Mon Apr 01 00:00:00 EST 2002, comment
        String value = instance.toString();
        assertTrue("author not found in string", value.indexOf("dion") != -1);
        assertTrue("comment not found in string", value.indexOf("comment") != -1);
        assertTrue("date not found in string", value.indexOf("Mon Apr 01") != -1);
    }

    /**
     * Test of getAuthor method
     */
    @Test
    public void testGetAuthor() {
        assertEquals("Author value not retrieved correctly", "dion", instance.getAuthor());
    }

    /**
     * Test of setAuthor method
     */
    @Test
    public void testSetAuthor() {
        instance.setAuthor("maven:dion");
        assertEquals("Author not set correctly", "maven:dion", instance.getAuthor());
    }

    /**
     * Test of getComment method
     */
    @Test
    public void testGetComment() {
        assertEquals("Comment value not retrieved correctly", "comment", instance.getComment());
    }

    /**
     * Test of setComment method
     */
    @Test
    public void testSetComment() {
        instance.setComment("maven:comment");
        assertEquals("Comment not set correctly", "maven:comment", instance.getComment());
    }

    /**
     * Test of getDate method
     */
    @Test
    public void testGetDate() {
        assertEquals("Date value not retrieved correctly", getDate(2002, 3, 1), instance.getDate());
    }

    /**
     * Test of setDate method with Date object
     */
    @Test
    public void testSetDate() {
        Calendar cal = Calendar.getInstance();
        Date date = cal.getTime();
        instance.setDate(date);
        assertEquals("Date value not set correctly", date, instance.getDate());
    }

    /**
     * Test of setDate method with String
     */
    @Test
    public void testSetDateFromString() {
        instance.setDate("2002/03/04 00:00:00");
        assertEquals("Date value not set correctly from a string", getDate(2002, 2, 4), instance.getDate());
    }

    /**
     * Test of getDateFormatted method
     */
    @Test
    public void testGetDateFormatted() {
        assertEquals("Date not formatted correctly", "2002-04-01", instance.getDateFormatted());
    }

    /**
     * Test of getDateFormatted method
     */
    @Test
    public void testGetTimeFormatted() {
        assertEquals("Time not formatted correctly", "00:00:00", instance.getTimeFormatted());
    }

    public static Date getDate(int year, int month, int day) {
        Calendar cal = Calendar.getInstance();

        cal.set(year, month, day, 0, 0, 0);
        cal.set(Calendar.MILLISECOND, 0);

        return cal.getTime();
    }

    @Test
    public void testEscapeValue() {
        assertEquals("", ChangeSet.escapeValue(""));
        assertEquals("&apos;", ChangeSet.escapeValue("'"));
        assertEquals("a", ChangeSet.escapeValue("a"));
        assertEquals("a&apos;", ChangeSet.escapeValue("a'"));
        assertEquals("&apos;a&apos;", ChangeSet.escapeValue("'a'"));

        assertEquals("a&lt;b&gt;c", ChangeSet.escapeValue("a<b>c"));
        assertEquals("&apos;&amp;;&lt;&gt;&quot;", ChangeSet.escapeValue("'&;<>\""));
    }

    @Test
    public void testEquals() {
        ChangeSet instance2 = createInstance();
        assertEquals(instance, instance2);

        instance2.setComment("another comment");
        assertNotEquals(instance2, instance);

        instance2.setComment("comment");
        assertEquals(instance, instance2);
    }

    @Test
    public void testHashCode() {
        int hashCode1 = instance.hashCode();
        instance.setAuthor("anotherAuthor");

        assertFalse(hashCode1 == instance.hashCode());
        instance.setAuthor("dion");
        assertEquals(hashCode1, instance.hashCode());
    }

    @Test
    public void testToXml() {
        String sXml = instance.toXML();
        assertNotNull(sXml);

        assertTrue(sXml.indexOf("<changelog-entry>") > -1);
        assertTrue(sXml.indexOf("</changelog-entry>") > -1);
    }

    @Test
    public void testToXmlWithFiles() {
        instance.addFile(new ChangeFile("maven1:dummy"));
        instance.addFile(new ChangeFile("maven2:dummy2"));

        String sXml = instance.toXML();
        assertNotNull(sXml);

        assertTrue(sXml.indexOf("<changelog-entry>") > -1);
        assertTrue(sXml.indexOf("</changelog-entry>") > -1);

        assertTrue(sXml.indexOf("<file>") > -1);
        assertTrue(sXml.indexOf("<name>maven1:dummy</name>") > -1);
        assertTrue(sXml.indexOf("<name>maven2:dummy2</name>") > -1);
    }
}
