using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.Serialization;
using skyscraper5.Skyscraper.Plugins;
using skyscraper8.Skyscraper.Plugins;

namespace skyscraper5.Skyscraper.IO.TunerInterface
{
    public sealed class TunerFactoryConnectionManager
    {
        private TunerFactoryConnectionManager()
        {
	        factories = PluginManager.GetInstance().GetTunerFactories();
	        if (factories.Count == 0)
	        {
		        throw new NullReferenceException("No tuner factories loaded!");
	        }
        }

        private static TunerFactoryConnectionManager _instance;

        public static TunerFactoryConnectionManager GetInstance()
        {
            if (_instance == null)
            {
                _instance = new TunerFactoryConnectionManager();
            }
            return _instance;
        }

        private ReadOnlyDictionary<TunerFactoryIdAttribute, ITunerFactory> factories;
        
        public ReadOnlyCollection<KeyValuePair<TunerFactoryIdAttribute, ITunerFactory>> GetKnownFactories()
        {
            ReadOnlyCollection<KeyValuePair<TunerFactoryIdAttribute, ITunerFactory>> readOnlyCollection = factories.ToList().AsReadOnly();
            return readOnlyCollection;
        }

        public static void ConfigureFactoryFromIni(KeyValuePair<TunerFactoryIdAttribute, ITunerFactory> bootingStorage, Ini ini)
        {
            string categoryName = String.Format("tunerFactory{0}", bootingStorage.Key.Id);
            PluginManager.GetInstance().AutoconfigureObject(categoryName, bootingStorage.Value);
        }

        public ITunerFactory AutoGetConfiguredTunerFactory()
        {
	        Ini ini = PluginManager.GetInstance().Ini;
	        int neededFactory = ini.ReadValue("startup", "tunerFactory", -2);
	        if (neededFactory == -2)
	        {
		        throw new NoTunerFactoryConfiguredException();
	        }

	        return GetTunerFactoryById(neededFactory);
        }

        public ITunerFactory GetTunerFactoryById(int neededFactory)
        {
	        Ini ini = PluginManager.GetInstance().Ini;
			ReadOnlyCollection<KeyValuePair<TunerFactoryIdAttribute, ITunerFactory>> readOnlyCollection = GetKnownFactories();
	        foreach (var keyValuePair in readOnlyCollection)
	        {
		        if (keyValuePair.Key.Id == neededFactory)
		        {
			        ConfigureFactoryFromIni(keyValuePair, ini);
			        return keyValuePair.Value;
		        }
	        }

	        throw new PluginsException(String.Format("Tuner Factory {0} is not loaded.", neededFactory));
        }
    }

}
