using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using log4net;
using skyscraper5.Skyscraper.Text.Encodings;

namespace skyscraper5.Skyscraper.Text
{
    public class SkyscraperEncodingProvider : EncodingProvider
    {
        private Dictionary<string, Encoding> _encodings;
        private static SkyscraperEncodingProvider _instance;
        public static SkyscraperEncodingProvider GetInstance()
        {
            if (_instance == null)
                _instance = new SkyscraperEncodingProvider();
            return _instance;
        }

        private SkyscraperEncodingProvider()
        {
            Type sourceAttribute = typeof(SkyscraperEncodingAttribute);
            _encodings = new Dictionary<string, Encoding>();
            Type[] types = GetType().Assembly.GetTypes();
            foreach (Type type in types)
            {
                object[] customAttributes = type.GetCustomAttributes(sourceAttribute, false);
                if (customAttributes.Length == 0)
                    continue;

                Encoding instance = (Encoding)Activator.CreateInstance(type);
                SkyscraperEncodingAttribute attribute = (SkyscraperEncodingAttribute)customAttributes[0];
                foreach (string attributeAlias in attribute.Aliases) 
                    _encodings.Add(attributeAlias,instance);
            }
        }

        private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
        private List<int> encodings;
		public override Encoding? GetEncoding(int codepage)
        {
            if (encodings == null)
                encodings = new List<int>();

            if (!encodings.Contains(codepage))
            {
	            logger.InfoFormat("Detected text encoding: {0}", codepage);
	            encodings.Add(codepage);
            }

            return null;
        }

        public override Encoding? GetEncoding(string name)
        {
            if (!name.StartsWith("dvb-"))
                return null;

            if (_encodings.ContainsKey(name))
                return _encodings[name];

            return new DummyEncoding(name);
        }
    }
}
