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

// .NET Compact Framework 1.0 has no support for Environment.GetEnvironmentVariable()
// .NET Framework version 1.0 / 1.1 do not have support for SetEnvironmentVariable which is used in these tests.
#if !NETCF && (NET_2_0 || NETSTANDARD2_0)

using System;
using System.IO;
using NUnit.Framework;

namespace log4net.Tests.Util
{
    [TestFixture]
    public class EnvironmentPatternConverterTest
    {
        private const string ENVIRONMENT_VARIABLE_NAME = "LOG4NET_TEST_TEMP";
        const string SYSTEM_LEVEL_VALUE = "SystemLevelEnvironmentValue";
        const string USER_LEVEL_VALUE = "UserLevelEnvironmentValue";
        const string PROCESS_LEVEL_VALUE = "ProcessLevelEnvironmentValue";

        [Test]
        public void SystemLevelEnvironmentVariable()
        {
            EnvironmentPatternConverter converter = new EnvironmentPatternConverter();
            try {
                Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, SYSTEM_LEVEL_VALUE, EnvironmentVariableTarget.Machine);
            }
            catch (System.Security.SecurityException) {
                Assert.Ignore("Test skipped as current user must not set system level environment variables");
            }

            converter.Option = ENVIRONMENT_VARIABLE_NAME;

			StringWriter sw = new StringWriter();
			converter.Convert(sw, null);

            Assert.AreEqual(SYSTEM_LEVEL_VALUE, sw.ToString(), "System level environment variable not expended correctly.");

            Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, null, EnvironmentVariableTarget.Machine);
        }

        [Test]
        public void UserLevelEnvironmentVariable()
        {
            EnvironmentPatternConverter converter = new EnvironmentPatternConverter();
            Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, USER_LEVEL_VALUE, EnvironmentVariableTarget.User);

            converter.Option = ENVIRONMENT_VARIABLE_NAME;

            StringWriter sw = new StringWriter();
            converter.Convert(sw, null);

            Assert.AreEqual(USER_LEVEL_VALUE, sw.ToString(), "User level environment variable not expended correctly.");

            Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, null, EnvironmentVariableTarget.User);
        }

        [Test]
        public void ProcessLevelEnvironmentVariable()
        {
            EnvironmentPatternConverter converter = new EnvironmentPatternConverter();
            Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, PROCESS_LEVEL_VALUE);

            converter.Option = ENVIRONMENT_VARIABLE_NAME;

            StringWriter sw = new StringWriter();
            converter.Convert(sw, null);

            Assert.AreEqual(PROCESS_LEVEL_VALUE, sw.ToString(), "Process level environment variable not expended correctly.");

            Environment.SetEnvironmentVariable(ENVIRONMENT_VARIABLE_NAME, null);
        }

        private class EnvironmentPatternConverter
        {
            private object target = null;

            public EnvironmentPatternConverter()
            {
                target = Utils.CreateInstance("log4net.Util.PatternStringConverters.EnvironmentPatternConverter,log4net");
            }

            public string Option
            {
                get { return Utils.GetProperty(target, "Option") as string; }
                set { Utils.SetProperty(target, "Option", value); }
            }

            public void Convert(TextWriter writer, object state)
            {
                Utils.InvokeMethod(target, "Convert", writer, state);
            }
        }
    }
}

#endif
