package com.yahoo.config.codegen;

import org.junit.Test;

import java.io.IOException;

import static com.yahoo.config.codegen.DefParserTest.assertLineFails;
import static com.yahoo.config.codegen.DefParserTest.createDefTemplate;
import static com.yahoo.config.codegen.DefParserTest.createParser;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;

/**
 * @author gjoranv
 * @author musum
 */
public class DefParserNamespaceTest {

    @Test
    public void namespace_is_set_on_root_node() {
        DefParser parser = createParser("version=1\nnamespace=myproject.config\na string\n");
        CNode root = parser.getTree();
        assertThat(root.getNamespace(), is("myproject.config"));
    }

    @Test
    public void package_is_used_as_namespace_when_no_namespace_is_given() {
        String PACKAGE = "com.github.myproject";
        DefParser parser = createParser("package=" + PACKAGE + "\n");
        CNode root = parser.getTree();
        assertThat(root.getNamespace(), is(PACKAGE));
    }

    @Test(expected = CodegenRuntimeException.class)
    public void uppercase_chars_are_not_allowed() {
        createParser("version=1\nnamespace=Foo\na string\n").getTree();
    }

    @Test(expected = CodegenRuntimeException.class)
    public void explicit_com_yahoo_prefix_is_not_allowed() {
        createParser("version=1\n" +
                             "namespace=com.yahoo.myproject.config\n" +
                             "a string\n").getTree();
    }

    @Test
    public void spaces_are_allowed_around_equals_sign() {
        DefParser parser = createParser("version=1\nnamespace =  myproject.config\na string\n");
        CNode root = parser.getTree();
        assertThat(root.getNamespace(), is("myproject.config"));
    }

    @Test
    public void empty_namespace_is_not_allowed() {
        assertLineFails("namespace");
    }

    @Test
    public void consecutive_dots_are_not_allowed() {
        assertLineFails("namespace=a..b");
    }

    @Test
    public void namespace_alters_def_md5() {
        DefParser parser = createParser("version=1\na string\n");
        CNode root = parser.getTree();

        parser = createParser("version=1\nnamespace=myproject.config\na string\n");
        CNode namespaceRoot = parser.getTree();

        assertThat(root.defMd5, not(namespaceRoot.defMd5));
    }


    @Test
    public void number_is_allowed_as_non_leading_char_in_namespace() throws IOException, DefParser.DefParserException {
        StringBuilder sb = createDefTemplate();
        String line = "namespace=a.b.c2\nfoo int\n";
        sb.append(line);
        createParser(sb.toString()).parse();
    }

    @Test
    public void number_is_not_allowed_as_namespace_start_char() throws IOException, DefParser.DefParserException {
        assertLineFails("namespace=2.a.b");
    }

    @Test
    public void number_is_not_allowed_as_leading_char_in_namespace_token() throws IOException, DefParser.DefParserException {
        assertLineFails("namespace=a.b.2c");
    }

    @Test
    public void underscore_in_namespace_is_allowed() throws IOException, DefParser.DefParserException {
        StringBuilder sb = createDefTemplate();
        String line = "namespace=a_b.c\nfoo int\n";
        sb.append(line);
        createParser(sb.toString()).parse();

        sb = createDefTemplate();
        line = "namespace=a_b.c_d\nfoo int\n";
        sb.append(line);
        createParser(sb.toString()).parse();
    }

}

@@ -641,34 +641,24 @@
 ject.config%5C
-na string%5C
 n%22);%0A       
@@ -1217,26 +1217,16 @@
 ace=Foo%5C
-na string%5C
 n%22).getT
@@ -1462,52 +1462,8 @@
 g%5Cn%22
- +%0A                             %22a string%5Cn%22
 ).ge
@@ -1624,34 +1624,24 @@
 ject.config%5C
-na string%5C
 n%22);%0A       
@@ -2069,26 +2069,16 @@
 rsion=1%5C
-na string%5C
 n%22);%0A   
@@ -2187,18 +2187,8 @@
 fig%5C
-na string%5C
 n%22);
@@ -2523,25 +2523,16 @@
 =a.b.c2%5C
-nfoo int%5C
 n%22;%0A    
@@ -3169,25 +3169,16 @@
 e=a_b.c%5C
-nfoo int%5C
 n%22;%0A    
@@ -3316,17 +3316,8 @@
 c_d%5C
-nfoo int%5C
 n%22;%0A

Remove redundant def parameters.