/*
 *
 * 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.
 *
*/

using System;
using System.Xml;
using log4net.Config;
using log4net.Core;
using log4net.Repository;
using log4net.Repository.Hierarchy;
using log4net.Tests.Appender;
using NUnit.Framework;

namespace log4net.Tests.Hierarchy
{
	[TestFixture]
	public class Hierarchy
	{
		[Test]
		public void SetRepositoryPropertiesInConfigFile()
		{
			// LOG4NET-53: Allow repository properties to be set in the config file
			XmlDocument log4netConfig = new XmlDocument();
			log4netConfig.LoadXml(@"
				<log4net>
				  <property>
					<key value=""two-plus-two"" />
					<value value=""4"" />
				  </property>
				  <appender name=""StringAppender"" type=""log4net.Tests.Appender.StringAppender, log4net.Tests"">
					<layout type=""log4net.Layout.SimpleLayout"" />
				  </appender>
				  <root>
					<level value=""ALL"" />
					<appender-ref ref=""StringAppender"" />
				  </root>
				</log4net>");

			ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
			XmlConfigurator.Configure(rep, log4netConfig["log4net"]);

			Assert.AreEqual("4", rep.Properties["two-plus-two"]);
			Assert.IsNull(rep.Properties["one-plus-one"]);
		}

		[Test]
		public void AddingMultipleAppenders()
		{
			CountingAppender alpha = new CountingAppender();
			CountingAppender beta = new CountingAppender();

			Repository.Hierarchy.Hierarchy hierarchy =
				(Repository.Hierarchy.Hierarchy)Utils.GetRepository();

			hierarchy.Root.AddAppender(alpha);
			hierarchy.Root.AddAppender(beta);
			hierarchy.Configured = true;

			ILog log = LogManager.GetLogger(GetType());
			log.Debug("Hello World");

			Assert.AreEqual(1, alpha.Counter);
			Assert.AreEqual(1, beta.Counter);
		}

		[Test]
		public void AddingMultipleAppenders2()
		{
			CountingAppender alpha = new CountingAppender();
			CountingAppender beta = new CountingAppender();

#if NETSTANDARD1_3
			BasicConfigurator.Configure(Utils.GetRepository(), alpha, beta);
#else
			BasicConfigurator.Configure(alpha, beta);
#endif

			ILog log = LogManager.GetLogger(GetType());
			log.Debug("Hello World");

			Assert.AreEqual(1, alpha.Counter);
			Assert.AreEqual(1, beta.Counter);
		}

		[Test]
	// LOG4NET-343
		public void LoggerNameCanConsistOfASingleDot()
		{
			XmlDocument log4netConfig = new XmlDocument();
			log4netConfig.LoadXml(@"
				<log4net>
				  <appender name=""StringAppender"" type=""log4net.Tests.Appender.StringAppender, log4net.Tests"">
					<layout type=""log4net.Layout.SimpleLayout"" />
				  </appender>
				  <root>
					<level value=""ALL"" />
					<appender-ref ref=""StringAppender"" />
				  </root>
				  <logger name=""."">
					<level value=""WARN"" />
				  </logger>
				</log4net>");

			ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
			XmlConfigurator.Configure(rep, log4netConfig["log4net"]);
		}

		[Test]
		public void LoggerNameCanConsistOfASingleNonDot()
		{
			XmlDocument log4netConfig = new XmlDocument();
			log4netConfig.LoadXml(@"
				<log4net>
				  <appender name=""StringAppender"" type=""log4net.Tests.Appender.StringAppender, log4net.Tests"">
					<layout type=""log4net.Layout.SimpleLayout"" />
				  </appender>
				  <root>
					<level value=""ALL"" />
					<appender-ref ref=""StringAppender"" />
				  </root>
				  <logger name=""L"">
					<level value=""WARN"" />
				  </logger>
				</log4net>");

			ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
			XmlConfigurator.Configure(rep, log4netConfig["log4net"]);
		}

		[Test]
		public void LoggerNameCanContainSequenceOfDots()
		{
			XmlDocument log4netConfig = new XmlDocument();
			log4netConfig.LoadXml(@"
				<log4net>
				  <appender name=""StringAppender"" type=""log4net.Tests.Appender.StringAppender, log4net.Tests"">
					<layout type=""log4net.Layout.SimpleLayout"" />
				  </appender>
				  <root>
					<level value=""ALL"" />
					<appender-ref ref=""StringAppender"" />
				  </root>
				  <logger name=""L..M"">
					<level value=""WARN"" />
				  </logger>
				</log4net>");

			ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
			XmlConfigurator.Configure(rep, log4netConfig["log4net"]);
		}
	}
}
