package com.diogonunes.jcolor.tests.unit;

import com.diogonunes.jcolor.Ansi;
import org.junit.Test;

import static com.diogonunes.jcolor.Ansi.*;
import static com.diogonunes.jcolor.Ansi.Attribute.*;
import static com.diogonunes.jcolor.tests.unit.DataGenerator.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

/**
 * Tests for Ansi class.
 */
public class TestAnsi {

    public static final String NEWLINE = System.getProperty("line.separator");

    @Test
    public void Configuration_EscapeCodes() {
        // ARRANGE

        // ACT

        // ASSERT
        char escapeChar = 27; // according to spec: https://en.wikipedia.org/wiki/ANSI_escape_code#Escape_sequences
        assertThat(PREFIX, equalTo(escapeChar + "["));
        assertThat(POSTFIX, equalTo("m"));
        assertThat(SEPARATOR, equalTo(";"));
    }

    @Test
    public void GenerateCode_ZeroAttributes() {
        // ARRANGE
        Attribute[] attributes = new Attribute[]{};

        // ACT
        String code = Ansi.generateCode(attributes);

        // ASSERT
        String expectedCode = PREFIX + POSTFIX;
        assertThat(code, equalTo(expectedCode));
    }

    @Test // Covers https://github.com/dialex/JCDP/issues/6
    public void GenerateCode_OneAttribute() {
        // ARRANGE
        Attribute[] attributes = new Attribute[]{BOLD};

        // ACT
        String code = Ansi.generateCode(attributes);

        // ASSERT
        String expectedCode = PREFIX + attributes[0] + POSTFIX;
        assertThat(code, equalTo(expectedCode));
    }

    @Test
    public void GenerateCode_MultipleAttributes_HandlesArray() {
        // ARRANGE
        Attribute[] attributes = new Attribute[]{BOLD, CYAN_TEXT};

        // ACT
        String code = Ansi.generateCode(attributes);

        // ASSERT
        String expectedCode = PREFIX + attributes[0] + SEPARATOR + attributes[1] + POSTFIX;
        assertThat(code, equalTo(expectedCode));
    }

    @Test
    public void GenerateCode_MultipleAttributes_HandlesMultipleParams() {
        // ARRANGE
        Attribute firstAttribute = BOLD;
        Attribute secondAttribute = CYAN_TEXT;

        // ACT
        String code = Ansi.generateCode(firstAttribute, secondAttribute);

        // ASSERT
        String expectedCode = PREFIX + firstAttribute + SEPARATOR + secondAttribute + POSTFIX;
        assertThat(code, equalTo(expectedCode));
    }

    @Test
    public void GenerateCode_MultipleAttributesWithValueNone() {
        // ARRANGE
        Attribute[] attributes = new Attribute[]{NONE, NONE, NONE};

        // ACT
        String code = Ansi.generateCode(attributes);

        // ASSERT
        String expectedCode = PREFIX + POSTFIX;
        assertThat(code, equalTo(expectedCode));
    }

    @Test // Covers https://github.com/dialex/JCDP/issues/6
    public void GenerateCode_SomeAttributesWithValueNone() {
        // ARRANGE
        Attribute[] attributes = new Attribute[]{NONE, CYAN_TEXT, NONE};

        // ACT
        String code = Ansi.generateCode(attributes);

        // ASSERT
        String expectedCode = PREFIX + attributes[1] + POSTFIX;
        assertThat(code, equalTo(expectedCode));
        int suffixIndex = code.lastIndexOf(POSTFIX);
        assertThat("Code ending in semicolon does not show color", code.charAt(suffixIndex - 1), is(not(';')));
    }

    @Test
    public void Colorize_TextWithoutLines() {
        // ARRANGE
        Attribute[] attributes = new Attribute[]{BLUE_BACK};
        String text = createText();

        // ACT
        String formattedText = Ansi.colorize(text, attributes);
        //System.out.println(formattedText);

        // ASSERT
        String expectedCode = Ansi.generateCode(attributes);
        assertThat(formattedText, startsWith(expectedCode));
        assertThat("Message should clear its format", formattedText, endsWith(Ansi.RESET));
    }

    @Test // Covers https://github.com/dialex/JCDP/issues/38
    public void Colorize_TextWithSingleLine() {
        // ARRANGE
        Attribute[] attributes = new Attribute[]{BLUE_BACK};
        String text = createTextLine();

        // ACT
        String formattedText = Ansi.colorize(text, attributes);
        //System.out.println(formattedText);

        // ASSERT
        String expectedCode = Ansi.generateCode(attributes);
        assertThat("Format must be cleared before changing line, to avoid format spillage",
                formattedText, endsWith(Ansi.RESET + NEWLINE));
    }

    @Test // Covers https://github.com/dialex/JCDP/issues/38
    public void Colorize_TextWithMultiplesLines() {
        // ARRANGE
        Attribute[] attributes = new Attribute[]{BLUE_BACK};
        String text1 = createTextWithId(1), text2 = createTextWithId(2);
        String fullText = text1 + NEWLINE + text2 + NEWLINE;

        // ACT
        String formattedText = Ansi.colorize(fullText, attributes);
        //System.out.println(formattedText);

        // ASSERT
        String expectedCode = Ansi.generateCode(attributes);
        assertThat("Middle lines preserve format", formattedText, containsString(expectedCode + text2 + Ansi.RESET));
        assertThat(formattedText, endsWith(Ansi.RESET + NEWLINE));
    }

}

@@ -1359,20 +1359,19 @@
 ibute%5B%5D%7B
-BOLD
+DIM
 %7D;%0A%0A    
@@ -1716,20 +1716,22 @@
 ibute%5B%5D%7B
-BOLD
+ITALIC
 , CYAN_T
@@ -2114,12 +2114,17 @@
 e = 
-BOLD
+UNDERLINE
 ;%0A  
@@ -2157,19 +2157,20 @@
 ibute = 
-CYA
+GREE
 N_TEXT;%0A
@@ -2978,20 +2978,20 @@
 %5D%7BNONE, 
-CYAN
+BLUE
 _TEXT, N
@@ -4075,36 +4075,37 @@
 new Attribute%5B%5D%7B
-BLUE
+GREEN
 _BACK%7D;%0A        
@@ -4677,36 +4677,35 @@
 new Attribute%5B%5D%7B
-BLUE
+RED
 _BACK%7D;%0A        

test more Attributes