/*
 * [The "BSD license"]
 *  Copyright (c) 2010 Terence Parr
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.stringtemplate.v4.test;

import org.junit.Assert;
import org.junit.Test;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STGroup;
import org.stringtemplate.v4.STGroupFile;
import org.stringtemplate.v4.STGroupString;

import static org.junit.Assert.assertEquals;

public class TestDollarDelimiters extends BaseTest {
    @Test public void testAttr() throws Exception {
        String template = "hi $name$!";
        ST st = new org.stringtemplate.v4.ST(template, '$', '$');
        st.add("name", "Ter");
        String expected = "hi Ter!";
        String result = st.render();
        assertEquals(expected, result);
    }

    @Test public void testParallelMap() throws Exception {
        STGroup group = new org.stringtemplate.v4.STGroup('$', '$');
        group.defineTemplate("test", "names,phones", "hi $names,phones:{n,p | $n$:$p$;}$");
        ST st = group.getInstanceOf("test");
        st.add("names", "Ter");
        st.add("names", "Tom");
        st.add("names", "Sumana");
        st.add("phones", "x5001");
        st.add("phones", "x5002");
        st.add("phones", "x5003");
        String expected =
            "hi Ter:x5001;Tom:x5002;Sumana:x5003;";
        String result = st.render();
        assertEquals(expected, result);
    }

    @Test public void testRefToAnotherTemplateInSameGroup() throws Exception {
        String dir = getRandomDir();
        String a = "a() ::= << <$b()$> >>\n";
        String b = "b() ::= <<bar>>\n";
        writeFile(dir, "a.st", a);
        writeFile(dir, "b.st", b);
        STGroup group = new org.stringtemplate.v4.STGroupDir(dir, '$', '$');
        org.stringtemplate.v4.ST st = group.getInstanceOf("a");
        String expected = " <bar> ";
        String result = st.render();
        assertEquals(expected, result);
    }

    @Test public void testDefaultArgument() throws Exception {
        String templates =
                "method(name) ::= <<"+newline+
                "$stat(name)$" +newline+
                ">>"+newline+
                "stat(name,value=\"99\") ::= \"x=$value$; // $name$\""+newline
                ;
        writeFile(tmpdir, "group.stg", templates);
        org.stringtemplate.v4.STGroup group = new STGroupFile(tmpdir+"/group.stg", '$', '$');
        org.stringtemplate.v4.ST b = group.getInstanceOf("method");
        b.add("name", "foo");
        String expecting = "x=99; // foo";
        String result = b.render();
        assertEquals(expecting, result);
    }

	/**
	 * This is part of a regression test for antlr/stringtemplate4#46.
	 * https://github.com/antlr/stringtemplate4/issues/46
	 */
	@Test public void testDelimitersClause() throws Exception {
		String templates =
				"delimiters \"$\", \"$\""+newline+
				"method(name) ::= <<"+newline+
				"$stat(name)$" +newline+
				">>"+newline+
				"stat(name,value=\"99\") ::= \"x=$value$; // $name$\""+newline
				;
		writeFile(tmpdir, "group.stg", templates);
		STGroup group = new STGroupFile(tmpdir+"/group.stg");
		ST b = group.getInstanceOf("method");
		b.add("name", "foo");
		String expecting = "x=99; // foo";
		String result = b.render();
		assertEquals(expecting, result);
	}

	/**
	 * This is part of a regression test for antlr/stringtemplate4#46.
	 * https://github.com/antlr/stringtemplate4/issues/46
	 */
	@Test public void testDelimitersClauseInGroupString() throws Exception {
		String templates =
				"delimiters \"$\", \"$\""+newline+
				"method(name) ::= <<"+newline+
				"$stat(name)$" +newline+
				">>"+newline+
				"stat(name,value=\"99\") ::= \"x=$value$; // $name$\""+newline
				;
		STGroup group = new STGroupString(templates);
		ST b = group.getInstanceOf("method");
		b.add("name", "foo");
		String expecting = "x=99; // foo";
		String result = b.render();
		assertEquals(expecting, result);
	}

	/**
	 * This is part of a regression test for antlr/stringtemplate4#66.
	 * https://github.com/antlr/stringtemplate4/issues/66
	 */
	@Test
	public void testImportTemplatePreservesDelimiters() {
		String groupFile =
			"group GenerateHtml;" + newline +
			"import \"html.st\"" + newline +
			"entry() ::= <<" + newline +
			"$html()$" + newline +
			">>" + newline;
		String htmlFile =
			"html() ::= <<" + newline +
			"<table style=\"stuff\">" + newline +
			">>" + newline;

		String dir = getRandomDir();
		writeFile(dir, "GenerateHtml.stg", groupFile);
		writeFile(dir, "html.st", htmlFile);

		STGroup group = new STGroupFile(dir + "/GenerateHtml.stg", '$', '$');

		// test html template directly
		ST st = group.getInstanceOf("html");
		Assert.assertNotNull(st);
		String expected = "<table style=\"stuff\">";
		String result = st.render();
		assertEquals(expected, result);

		// test from entry template
		st = group.getInstanceOf("entry");
		Assert.assertNotNull(st);
		expected = "<table style=\"stuff\">";
		result = st.render();
		assertEquals(expected, result);
	}

	/**
	 * This is part of a regression test for antlr/stringtemplate4#66.
	 * https://github.com/antlr/stringtemplate4/issues/66
	 */
	@Test
	public void testImportGroupPreservesDelimiters() {
		String groupFile =
			"group GenerateHtml;" + newline +
			"import \"HtmlTemplates.stg\"" + newline +
			"entry() ::= <<" + newline +
			"$html()$" + newline +
			">>" + newline;
		String htmlFile =
			"html() ::= <<" + newline +
			"<table style=\"stuff\">" + newline +
			">>" + newline;

		String dir = getRandomDir();
		writeFile(dir, "GenerateHtml.stg", groupFile);
		writeFile(dir, "HtmlTemplates.stg", htmlFile);

		STGroup group = new STGroupFile(dir + "/GenerateHtml.stg", '$', '$');

		// test html template directly
		ST st = group.getInstanceOf("html");
		Assert.assertNotNull(st);
		String expected = "<table style=\"stuff\">";
		String result = st.render();
		assertEquals(expected, result);

		// test from entry template
		st = group.getInstanceOf("entry");
		Assert.assertNotNull(st);
		expected = "<table style=\"stuff\">";
		result = st.render();
		assertEquals(expected, result);
	}

	/**
	 * This is part of a regression test for antlr/stringtemplate4#66.
	 * https://github.com/antlr/stringtemplate4/issues/66
	 */
	@Test
	public void testDelimitersClauseOverridesConstructorDelimiters() {
		String groupFile =
			"group GenerateHtml;" + newline +
			"delimiters \"$\", \"$\"" + newline +
			"import \"html.st\"" + newline +
			"entry() ::= <<" + newline +
			"$html()$" + newline +
			">>" + newline;
		String htmlFile =
			"html() ::= <<" + newline +
			"<table style=\"stuff\">" + newline +
			">>" + newline;

		String dir = getRandomDir();
		writeFile(dir, "GenerateHtml.stg", groupFile);
		writeFile(dir, "html.st", htmlFile);

		STGroup group = new STGroupFile(dir + "/GenerateHtml.stg", '<', '>');

		// test html template directly
		ST st = group.getInstanceOf("html");
		Assert.assertNotNull(st);
		String expected = "<table style=\"stuff\">";
		String result = st.render();
		assertEquals(expected, result);

		// test from entry template
		st = group.getInstanceOf("entry");
		Assert.assertNotNull(st);
		expected = "<table style=\"stuff\">";
		result = st.render();
		assertEquals(expected, result);
	}

	/**
	 * This is part of a regression test for antlr/stringtemplate4#66.
	 * https://github.com/antlr/stringtemplate4/issues/66
	 */
	@Test
	public void testDelimitersClauseOverridesInheritedDelimiters() {
		String groupFile =
			"group GenerateHtml;" + newline +
			"delimiters \"<\", \">\"" + newline +
			"import \"HtmlTemplates.stg\"" + newline +
			"entry() ::= <<" + newline +
			"<html()>" + newline +
			">>" + newline;
		String htmlFile =
			"delimiters \"$\", \"$\"" + newline +
			"html() ::= <<" + newline +
			"<table style=\"stuff\">" + newline +
			">>" + newline;

		String dir = getRandomDir();
		writeFile(dir, "GenerateHtml.stg", groupFile);
		writeFile(dir, "HtmlTemplates.stg", htmlFile);

		STGroup group = new STGroupFile(dir + "/GenerateHtml.stg");

		// test html template directly
		ST st = group.getInstanceOf("html");
		Assert.assertNotNull(st);
		String expected = "<table style=\"stuff\">";
		String result = st.render();
		assertEquals(expected, result);

		// test from entry template
		st = group.getInstanceOf("entry");
		Assert.assertNotNull(st);
		expected = "<table style=\"stuff\">";
		result = st.render();
		assertEquals(expected, result);
	}
}
