// ***************************************************************************************************************************
// * 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.juneau.config;

import static org.junit.Assert.*;

import org.apache.juneau.config.event.*;
import org.apache.juneau.config.store.*;
import org.apache.juneau.internal.*;
import org.junit.*;

/**
 * Validates aspects of config imports.
 */
public class ConfigImportsTest {

	//-----------------------------------------------------------------------------------------------------------------
	// Value inheritance
	//-----------------------------------------------------------------------------------------------------------------

	@Test
	public void oneSimpleImport() throws Exception {
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();
		ms.write("A", "", "x=1");
		ms.write("B", "", "<A>");
		Config c = Config
			.create("B")
			.store(ms)
			.build();
		assertEquals("1", c.getString("x"));

		c.set("x", "2");
		c.commit();
		assertEquals("x=1", ms.read("A"));
		assertEquals("x = 2\n", ms.read("B"));
	}

	@Test
	public void twoSimpleImports() throws Exception {
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();
		ms.write("A1", "", "x=1");
		ms.write("A2", "", "y=2");
		ms.write("B", "", "<A1>\n<A2>");
		Config c = Config.create("B").store(ms).build();
		assertEquals("1", c.getString("x"));
		assertEquals("2", c.getString("y"));

		c.set("x", "3");
		c.set("y", "4");
		c.commit();
		assertEquals("x=1", ms.read("A1"));
		assertEquals("y=2", ms.read("A2"));
		assertEquals("x = 3\ny = 4\n", ms.read("B"));
	}

	@Test
	public void nestedImports() throws Exception {
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();
		ms.write("A1", "", "x=1");
		ms.write("A2", "", "<A1>\ny=2");
		ms.write("B", "", "<A2>");
		Config c = Config.create("B").store(ms).build();
		assertEquals("1", c.getString("x"));
		assertEquals("2", c.getString("y"));

		c.set("x", "3");
		c.set("y", "4");
		c.commit();
		assertEquals("x=1", ms.read("A1"));
		assertEquals("<A1>\ny=2", ms.read("A2"));
		assertEquals("x = 3\ny = 4\n", ms.read("B"));
	}

	@Test
	public void nestedImportsLoop() throws Exception {
		// This shouldn't blow up.
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();
		ms.write("A1", "", "<A2>\nx=1");
		ms.write("A2", "", "<A1>\ny=2");
		ms.write("B", "", "<A2>");
		try {
			Config.create("B").store(ms).build();
			fail("Exception expected.");
		} catch (Exception e) {
			// OK
		}
	}

	@Test
	public void importNotFound() throws Exception {
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();
		ms.write("B", "", "<A>\nx=1");
		Config c = Config.create("B").store(ms).build();
		assertEquals("1", c.getString("x"));
	}

	@Test
	public void noOverwriteOnImports() throws Exception {
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();
		ms.write("A", "", "x=1");
		ms.write("B", "", "<A>");
		Config c = Config.create("B").store(ms).build();
		assertEquals("1", c.getString("x"));
		c.set("x", "2");
		assertEquals("2", c.getString("x"));
		assertEquals("1", Config.create("A").store(ms).build().getString("x"));
	}

	@Test
	public void overlappingSections() throws Exception {
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();
		ms.write("A", "", "x=1\n[A]\na1=1");
		ms.write("B", "", "<A>\n[A]\na2=2");
		Config c = Config.create("B").store(ms).build();
		assertEquals("1", c.getString("A/a1"));
		assertEquals("2", c.getString("A/a2"));
	}

	@Test
	public void overlappingSectionsImportAtEnd() throws Exception {
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();
		ms.write("A", "", "x=1\n[A]\na1=1");
		ms.write("B", "", "[A]\na2=2\n<A>");
		Config c = Config.create("B").store(ms).build();
		assertEquals("1", c.getString("A/a1"));
		assertEquals("2", c.getString("A/a2"));
	}

	@Test
	public void overlappingSectionsAndValues() throws Exception {
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();
		ms.write("A", "", "x=1\n[A]\na1=1");
		ms.write("B", "", "<A>\n[A]\na1=2");
		Config c = Config.create("B").store(ms).build();
		assertEquals("2", c.getString("A/a1"));
	}

	//-----------------------------------------------------------------------------------------------------------------
	// Listeners
	//-----------------------------------------------------------------------------------------------------------------

	public static class TestListener implements ConfigEventListener {

		private boolean triggered;
		private ConfigEvents events;

		@Override
		public void onConfigChange(ConfigEvents events) {
			this.triggered = true;
			this.events = events;
		}

		public TestListener reset() {
			triggered = false;
			events = null;
			return this;
		}

		public boolean isTriggered() {
			return triggered;
		}

		public ConfigEvents getEvents() {
			return events;
		}

		public String getNewValue(String section, String key) {
			if (events.size() == 0)
				return null;
			for (ConfigEvent ce : events)
				if (StringUtils.isEquals(section, ce.getSection()) && StringUtils.isEquals(key, ce.getKey()))
					return ce.getValue();
			return null;
		}
	}

	@Test
	public void testUpdateOnParent() throws Exception {
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();

		ms.write("A", "", "x=1\n[A]\na1=1");
		ms.write("B", "", "<A>\n[B]\nb1=2");

		Config ca = Config.create("A").store(ms).build();
		Config cb = Config.create("B").store(ms).build();

		assertEquals(2, ca.getConfigMap().getListeners().size());
		assertEquals(1, cb.getConfigMap().getListeners().size());

		TestListener l = new TestListener();
		cb.addListener(l);

		assertEquals(0, ca.getListeners().size());
		assertEquals(1, cb.getListeners().size());

		ms.write("A", "x=1\n[A]\na1=1", "x=1\n[A]\na1=2");

		assertTrue(l.isTriggered());
		assertEquals(1, l.getEvents().size());
		assertEquals("2", l.getNewValue("A", "a1"));

		assertEquals("2", cb.get("A/a1"));
		assertEquals("2", cb.get("B/b1"));

		l.reset();
		cb.removeListener(l);
		assertEquals(0, ca.getListeners().size());
		assertEquals(0, cb.getListeners().size());

		ms.write("A", "x=1\n[A]\na1=2", "x=1\n[A]\na1=3");

		assertFalse(l.isTriggered());

		assertEquals("3", cb.get("A/a1"));
		assertEquals("2", cb.get("B/b1"));
	}

	@Test
	public void testUpdateOnGrandParent() throws Exception {
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();

		ms.write("A", "", "x=1\n[A]\na1=1");
		ms.write("B", "", "<A>\n[B]\nb1=2");
		ms.write("C", "", "<B>\n[C]\nc1=3");

		Config ca = Config.create("A").store(ms).build();
		Config cb = Config.create("B").store(ms).build();
		Config cc = Config.create("C").store(ms).build();

		assertEquals(3, ca.getConfigMap().getListeners().size());
		assertEquals(2, cb.getConfigMap().getListeners().size());
		assertEquals(1, cc.getConfigMap().getListeners().size());

		TestListener l = new TestListener();
		cc.addListener(l);

		assertEquals(0, ca.getListeners().size());
		assertEquals(0, cb.getListeners().size());
		assertEquals(1, cc.getListeners().size());

		ms.write("A", "x=1\n[A]\na1=1", "x=1\n[A]\na1=2");

		assertTrue(l.isTriggered());
		assertEquals(1, l.getEvents().size());
		assertEquals("2", l.getNewValue("A", "a1"));

		assertEquals("2", cc.get("A/a1"));
		assertEquals("2", cc.get("B/b1"));
		assertEquals("3", cc.get("C/c1"));

		l.reset();
		cc.removeListener(l);
		assertEquals(0, ca.getListeners().size());
		assertEquals(0, cb.getListeners().size());
		assertEquals(0, cc.getListeners().size());

		ms.write("A", "x=1\n[A]\na1=2", "x=1\n[A]\na1=3");

		assertFalse(l.isTriggered());

		assertEquals("3", cc.get("A/a1"));
		assertEquals("2", cc.get("B/b1"));
		assertEquals("3", cc.get("C/c1"));
	}

	@Test
	public void testUpdateOnParentSameSection() throws Exception {
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();

		ms.write("A", "", "x=1\n[A]\na1=1");
		ms.write("B", "", "<A>\n[A]\nb1=2");

		Config ca = Config.create("A").store(ms).build();
		Config cb = Config.create("B").store(ms).build();

		assertEquals(2, ca.getConfigMap().getListeners().size());
		assertEquals(1, cb.getConfigMap().getListeners().size());

		TestListener l = new TestListener();
		cb.addListener(l);

		ms.write("A", "x=1\n[A]\na1=1", "x=1\n[A]\na1=2");

		assertTrue(l.isTriggered());
		assertEquals(1, l.getEvents().size());
		assertEquals("2", l.getNewValue("A", "a1"));

		assertEquals("2", cb.get("A/a1"));
		assertEquals("2", cb.get("A/b1"));

		l.reset();
		cb.removeListener(l);
		assertEquals(0, ca.getListeners().size());
		assertEquals(0, cb.getListeners().size());

		ms.write("A", "x=1\n[A]\na1=2", "x=1\n[A]\na1=3");

		assertFalse(l.isTriggered());

		assertEquals("3", cb.get("A/a1"));
		assertEquals("2", cb.get("A/b1"));
	}

	@Test
	public void testUpdateOnParentSameSectionSameKey() throws Exception {
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();

		ms.write("A", "", "x=1\n[A]\na1=1");
		ms.write("B", "", "<A>\n[A]\na1=2");

		Config ca = Config.create("A").store(ms).build();
		Config cb = Config.create("B").store(ms).build();

		assertEquals(2, ca.getConfigMap().getListeners().size());
		assertEquals(1, cb.getConfigMap().getListeners().size());

		TestListener l = new TestListener();
		cb.addListener(l);

		ms.write("A", "x=1\n[A]\na1=1", "x=1\n[A]\na1=3");

		assertFalse(l.isTriggered());
		assertEquals("2", cb.get("A/a1"));
	}

	@Test
	public void testUpdateOnGrandParentSameSection() throws Exception {
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();

		ms.write("A", "", "x=1\n[A]\na1=1");
		ms.write("B", "", "<A>\n[A]\na1=2");
		ms.write("C", "", "<B>\n[A]\na1=3");

		Config ca = Config.create("A").store(ms).build();
		Config cb = Config.create("B").store(ms).build();
		Config cc = Config.create("C").store(ms).build();

		assertEquals(3, ca.getConfigMap().getListeners().size());
		assertEquals(2, cb.getConfigMap().getListeners().size());
		assertEquals(1, cc.getConfigMap().getListeners().size());

		TestListener l = new TestListener();
		cc.addListener(l);

		ms.write("A", "x=1\n[A]\na1=1", "x=1\n[A]\na1=4");

		assertFalse(l.isTriggered());
		assertEquals("3", cc.get("A/a1"));
	}

	//-----------------------------------------------------------------------------------------------------------------
	// Listeners and dynamically modifying imports
	//-----------------------------------------------------------------------------------------------------------------

	@Test
	public void testUpdateOnParentDynamic() throws Exception {
		ConfigMemoryStore ms = ConfigMemoryStore.create().build();

		ms.write("A", "", "x=1\ny=1\n[A]\na1=1");
		ms.write("B", "", "x=2\n[B]\nb1=2");

		Config ca = Config.create("A").store(ms).build();
		Config cb = Config.create("B").store(ms).build();

		assertEquals(1, ca.getConfigMap().getListeners().size());
		assertEquals(1, cb.getConfigMap().getListeners().size());

		TestListener l = new TestListener();
		cb.addListener(l);

		assertEquals(0, ca.getListeners().size());
		assertEquals(1, cb.getListeners().size());

		ms.write("B", "x=2\n[B]\nb1=2", "x=2\n<A>\n[B]\nb1=2");

		assertTrue(l.isTriggered());
		assertEquals(2, l.getEvents().size());  // Should contain [SET(y = 1), SET(A/a1 = 1)]
		assertEquals("1", l.getNewValue("A", "a1"));

		assertEquals("1", cb.get("A/a1"));
		assertEquals("2", cb.get("B/b1"));

		assertEquals(2, ca.getConfigMap().getListeners().size());
		assertEquals(1, cb.getConfigMap().getListeners().size());

		l.reset();

		ms.write("B", "x=2\n<A>\n[B]\nb1=2", "x=2\n[B]\nb1=2");

		assertTrue(l.isTriggered());
		assertEquals(2, l.getEvents().size());  // Should contain [REMOVE_ENTRY(y), REMOVE_ENTRY(A/a1)]
 		assertEquals(null, l.getNewValue("A", "a1"));

		assertNull(cb.get("A/a1"));
		assertEquals("2", cb.get("B/b1"));

		l.reset();
		cb.removeListener(l);
		assertEquals(0, ca.getListeners().size());
		assertEquals(0, cb.getListeners().size());

		ms.write("B", "x=2\n[B]\nb1=2", "x=2\n<A>\n[B]\nb1=2");

		assertFalse(l.isTriggered());

		assertEquals("1", cb.get("A/a1"));
		assertEquals("2", cb.get("B/b1"));
	}
}
