#region Apache License
//
// 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.
//
#endregion

using System;
using System.Collections;
using System.Globalization;
using log4net;
using log4net.Appender;
using log4net.Layout;
using log4net.Repository.Hierarchy;

namespace NotLogging;

/// <summary>
/// NotLogging
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters")]
internal static class NotLogging
{
  #region Init Code

  private static int _warmupCycles = 10000;
  private static readonly ILog _shortLog = LogManager.GetLogger("A0123456789");
  private static readonly ILog _mediumLog = LogManager.GetLogger("A0123456789.B0123456789");
  private static readonly ILog _longLog = LogManager.GetLogger("A0123456789.B0123456789.C0123456789");
  private static readonly ILog _inexistentShortLog = LogManager.GetLogger("I0123456789");
  private static readonly ILog _inexistentMediumLog = LogManager.GetLogger("I0123456789.B0123456789");
  private static readonly ILog _inexistentLongLog = LogManager.GetLogger("I0123456789.B0123456789.C0123456789");
  private static readonly ILog[] _logArray = 
  [
    _shortLog,
    _mediumLog,
    _longLog,
    _inexistentShortLog,
    _inexistentMediumLog,
    _inexistentLongLog
  ];
  private static readonly TimedTest[] _timedTests = 
  [
    new SimpleMessage_Bare(),
    new SimpleMessage_Array(),
    new SimpleMessage_MethodGuard_Bare(),
    new SimpleMessage_LocalGuard_Bare(),
    new ComplexMessage_Bare(),
    new ComplexMessage_Array(),
    new ComplexMessage_MethodGuard_Bare(),
    new ComplexMessage_MethodGuard_Array(),
    new ComplexMessage_MemberGuard_Bare(),
    new ComplexMessage_LocalGuard_Bare()
  ];

  private static void Usage()
  {
    Console.WriteLine(
      "Usage: NotLogging <true|false> <runLength>" + Environment.NewLine +
      "\t true indicates shipped code" + Environment.NewLine +
      "\t false indicates code in development" + Environment.NewLine +
      "\t runLength is an int representing the run length of loops" + Environment.NewLine +
      "\t We suggest that runLength be at least 1000000 (1 million).");
    Environment.Exit(1);
  }

  /// <summary>
  /// Program wide initialization method
  /// </summary>
  /// <param name="args"></param>
  [System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters")]
  private static int ProgramInit(string[] args)
  {
    if (args is not string[] { Length: 2 })
    {
      Usage();
      return 0;
    }
    if (!int.TryParse(args[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out int runLength))
    {
      Usage();
      return 0;
    }

    ConsoleAppender appender = new() { Layout = new SimpleLayout() };
    ((SimpleLayout)appender.Layout).ActivateOptions();
    appender.ActivateOptions();

    if ("false" == args[0])
    {
      // nothing to do
    }
    else if ("true" == args[0])
    {
      Console.WriteLine("Flagging as shipped code.");
      ((Hierarchy)LogManager.GetRepository()).Threshold = log4net.Core.Level.Warn;
    }
    else
    {
      Usage();
    }

    ((Logger)_shortLog.Logger).Level = log4net.Core.Level.Info;
    ((Hierarchy)LogManager.GetRepository()).Root.Level = log4net.Core.Level.Info;
    ((Hierarchy)LogManager.GetRepository()).Root.AddAppender(appender);

    return runLength;
  }

  #endregion

  /// <summary>
  /// The main entry point for the application.
  /// </summary>
  [STAThread]
  private static void Main(string[] argv)
  {
    if (System.Diagnostics.Debugger.IsAttached)
    {
      _warmupCycles = 0;
      argv = ["false", "2"];
    }
    if (argv.Length != 2)
    {
      Usage();
    }

    int runLength = ProgramInit(argv);

    Console.WriteLine();
    Console.Write("Warming Up...");

    if (_warmupCycles > 0)
    {
      foreach (ILog logger in _logArray)
      {
        foreach (TimedTest timedTest in _timedTests)
        {
          timedTest.Run(logger, _warmupCycles);
        }
      }
    }

    Console.WriteLine("Done");
    Console.WriteLine();

    // Calculate maximum description length
    int maxDescLen = 0;
    foreach (TimedTest timedTest in _timedTests)
    {
      maxDescLen = Math.Max(maxDescLen, timedTest.Description.Length);
    }

    string formatString = "{0,-" + (maxDescLen + 1) + "} {1,9:G} ticks. Log: {2}";
    double delta;

    ArrayList averageData = [];

    foreach (TimedTest timedTest in _timedTests)
    {
      double total = 0;
      foreach (ILog logger in _logArray)
      {
        delta = timedTest.Run(logger, runLength);
        Console.WriteLine(string.Format(formatString, timedTest.Description, delta, ((Logger)logger.Logger).Name));

        total += delta;
      }
      Console.WriteLine();

      averageData.Add(new object[] { timedTest, total / ((double)_logArray.Length) });
    }
    Console.WriteLine();
    Console.WriteLine("Averages:");
    Console.WriteLine();

    foreach (object[] pair in averageData)
    {
      string avgFormatString = "{0,-" + (maxDescLen + 1) + "} {1,9:G} ticks.";
      Console.WriteLine(string.Format(avgFormatString, ((TimedTest)pair[0]).Description, ((double)pair[1])));
    }
  }

  internal abstract class TimedTest
  {
    public abstract double Run(ILog log, long runLength);
    public abstract string Description { get; }
  }

  #region Tests calling Debug(string)

  internal sealed class SimpleMessage_Bare : TimedTest
  {
    public override double Run(ILog log, long runLength)
    {
      DateTime before = DateTime.Now;
      for (int i = 0; i < runLength; i++)
      {
        log.Debug("msg");
      }
      DateTime after = DateTime.Now;
      TimeSpan diff = after - before;
      return ((double)diff.Ticks) / ((double)runLength);
    }

    public override string Description => "log.Debug(\"msg\");";
  }

  internal sealed class ComplexMessage_MethodGuard_Bare : TimedTest
  {
    public override double Run(ILog log, long runLength)
    {
      DateTime before = DateTime.Now;
      for (int i = 0; i < runLength; i++)
      {
        if (log.IsDebugEnabled)
        {
          log.Debug("msg" + i + "msg");
        }
      }
      DateTime after = DateTime.Now;
      TimeSpan diff = after - before;
      return ((double)diff.Ticks) / ((double)runLength);
    }

    public override string Description => "if(log.IsDebugEnabled) log.Debug(\"msg\" + i + \"msg\");";
  }

  internal sealed class ComplexMessage_Bare : TimedTest
  {
    public override double Run(ILog log, long runLength)
    {
      DateTime before = DateTime.Now;
      for (int i = 0; i < runLength; i++)
      {
        log.Debug("msg" + i + "msg");
      }
      DateTime after = DateTime.Now;
      TimeSpan diff = after - before;
      return ((double)diff.Ticks) / ((double)runLength);
    }

    public override string Description => "log.Debug(\"msg\" + i + \"msg\");";
  }

  #endregion

  #region Tests calling Debug(new object[] { ... })

  internal sealed class SimpleMessage_Array : TimedTest
  {
    public override double Run(ILog log, long runLength)
    {
      DateTime before = DateTime.Now;
      for (int i = 0; i < runLength; i++)
      {
        log.Debug(new object[] { "msg" });
      }
      DateTime after = DateTime.Now;
      TimeSpan diff = after - before;
      return ((double)diff.Ticks) / ((double)runLength);
    }

    public override string Description => "log.Debug(new object[] { \"msg\" });";
  }

  internal sealed class ComplexMessage_MethodGuard_Array : TimedTest
  {
    public override double Run(ILog log, long runLength)
    {
      DateTime before = DateTime.Now;
      for (int i = 0; i < runLength; i++)
      {
        if (log.IsDebugEnabled)
        {
          log.Debug(new object[] { "msg", i, "msg" });
        }
      }
      DateTime after = DateTime.Now;
      TimeSpan diff = after - before;
      return ((double)diff.Ticks) / ((double)runLength);
    }

    public override string Description => "if(log.IsDebugEnabled) log.Debug(new object[] { \"msg\" , i , \"msg\" });";
  }

  internal sealed class ComplexMessage_Array : TimedTest
  {
    public override double Run(ILog log, long runLength)
    {
      DateTime before = DateTime.Now;
      for (int i = 0; i < runLength; i++)
      {
        log.Debug(new object[] { "msg", i, "msg" });
      }
      DateTime after = DateTime.Now;
      TimeSpan diff = after - before;
      return ((double)diff.Ticks) / ((double)runLength);
    }

    public override string Description => "log.Debug(new object[] { \"msg\" , i , \"msg\" });";
  }

  #endregion

  #region Tests calling Debug(string) (using class members)

  internal sealed class ComplexMessage_MemberGuard_Bare : TimedTest
  {
    public override double Run(ILog log, long runLength) => new Impl(log).Run(runLength);

    public override string Description => "if (m_isEnabled) log.Debug(\"msg\" + i + \"msg\");";

    private sealed class Impl
    {
      private readonly ILog _log;
      private readonly bool _isEnabled;

      public Impl(ILog log)
      {
        this._log = log;
        _isEnabled = this._log.IsDebugEnabled;
      }

      public double Run(long runLength)
      {

        DateTime before = DateTime.Now;
        for (int i = 0; i < runLength; i++)
        {
          if (_isEnabled)
          {
            _log.Debug("msg" + i + "msg");
          }
        }
        DateTime after = DateTime.Now;
        TimeSpan diff = after - before;
        return ((double)diff.Ticks) / ((double)runLength);
      }
    }
  }

  internal sealed class SimpleMessage_LocalGuard_Bare : TimedTest
  {
    public override double Run(ILog log, long runLength)
    {
      bool isEnabled = log.IsDebugEnabled;

      DateTime before = DateTime.Now;
      for (int i = 0; i < runLength; i++)
      {
        if (isEnabled)
        {
          log.Debug("msg");
        }
      }
      DateTime after = DateTime.Now;
      TimeSpan diff = after - before;
      return ((double)diff.Ticks) / ((double)runLength);
    }

    public override string Description => "if (isEnabled) log.Debug(\"msg\");";
  }

  internal sealed class SimpleMessage_MethodGuard_Bare : TimedTest
  {
    public override double Run(ILog log, long runLength)
    {
      DateTime before = DateTime.Now;
      for (int i = 0; i < runLength; i++)
      {
        if (log.IsDebugEnabled)
        {
          log.Debug("msg");
        }
      }
      DateTime after = DateTime.Now;
      TimeSpan diff = after - before;
      return ((double)diff.Ticks) / ((double)runLength);
    }

    public override string Description => "if (log.IsDebugEnabled) log.Debug(\"msg\");";
  }

  internal sealed class ComplexMessage_LocalGuard_Bare : TimedTest
  {
    public override double Run(ILog log, long runLength)
    {
      bool isEnabled = log.IsDebugEnabled;

      DateTime before = DateTime.Now;
      for (int i = 0; i < runLength; i++)
      {
        if (isEnabled)
        {
          log.Debug("msg" + i + "msg");
        }
      }
      DateTime after = DateTime.Now;
      TimeSpan diff = after - before;
      return ((double)diff.Ticks) / ((double)runLength);
    }

    public override string Description => "if (isEnabled) log.Debug(\"msg\" + i + \"msg\");";
  }
  #endregion
}