package com.atlassian.bitbucket.mesh.app;

import org.junit.Test;

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

import static org.junit.Assert.*;

public class BuildInfoTest {

    private static final String FORMAT = "yyyy-MM-dd'T'HH:mm:ss,SSSZ";
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(FORMAT, Locale.ROOT);

    private final OffsetDateTime timestamp = OffsetDateTime.now();

    @Test
    public void testAll() {
        //The expected timestamp needs to be formatted using the pattern specified by FORMAT,
        //so that it has the same level of precision as the timestamps in BuildInfo.
        OffsetDateTime expectedTimestamp = OffsetDateTime.parse(FORMATTER.format(timestamp), FORMATTER);

        BuildInfo buildInfo = new BuildInfo(createProperties());
        assertEquals(String.valueOf(2L * 1000L * 1000L), buildInfo.getBuildNumber());
        assertEquals(expectedTimestamp, buildInfo.getBuildTimestamp());
        assertEquals("2", buildInfo.getBuildVersion());
        assertEquals("0123456789ABCDEF0123456789ABCDEF01234567", buildInfo.getCommitHash());
        assertEquals(expectedTimestamp, buildInfo.getCommitTimestamp());
        assertEquals("0123456", buildInfo.getDisplayCommitHash()); //Substring to 7, git style
    }

    @Test
    public void testBadBuildTimestamp() {
        BuildProperties properties = createProperties();
        properties.setTimestamp(null);

        BuildInfo buildInfo = new BuildInfo(properties);
        assertNotNull(buildInfo.getBuildTimestamp());
    }

    @Test
    public void testBadCommitTimestamp() {
        BuildProperties properties = createProperties();
        properties.getCommit().setTimestamp(null);

        BuildInfo buildInfo = new BuildInfo(properties);
        assertNull(buildInfo.getCommitTimestamp());
    }

    @Test
    public void testIsCompatible() {
        BuildProperties properties = createProperties();
        properties.setVersion("4.11.1");

        BuildInfo buildInfo = new BuildInfo(properties);
        assertTrue(buildInfo.isCompatible("4014004"));   //4.14.4
        assertTrue(buildInfo.isCompatible("4001004"));   //4.1.4
        assertFalse(buildInfo.isCompatible("40001004")); //40.1.4
        assertFalse(buildInfo.isCompatible("5011001"));  //5.11.1
        assertFalse(buildInfo.isCompatible("3001004"));  //3.1.4
    }

    @Test
    public void testIsCompatibleDoubleDigitMajorVersion() {
        BuildProperties properties = createProperties();
        properties.setVersion("10.13.3");

        BuildInfo buildInfo = new BuildInfo(properties);
        assertTrue(buildInfo.isCompatible("10014004"));  //10.14.4
        assertTrue(buildInfo.isCompatible("10001004"));  //10.1.4
        assertFalse(buildInfo.isCompatible("1001004"));  //1.1.4
        assertFalse(buildInfo.isCompatible("5011001"));  //5.11.1
        assertFalse(buildInfo.isCompatible("13001004")); //13.1.4
    }

    private BuildProperties createProperties() {
        BuildProperties properties = new BuildProperties();
        properties.getCommit().setHash("0123456789ABCDEF0123456789ABCDEF01234567");
        properties.getCommit().setTimestamp(Long.toString(timestamp.toInstant().toEpochMilli()));
        properties.setTimestamp(FORMATTER.format(timestamp));
        properties.setTimestampFormat(FORMAT);
        properties.setVersion("2");

        return properties;
    }
}
