using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace TINK.Services.BluetoothLock
{
    /// <summary> Manages Locks services and related configuration parameter. </summary>
    public class LocksServicesContainerMutable : IEnumerable<string>
    {
        /// <summary> Manages the different types of LocksService objects.</summary>
        private ServicesContainerMutable<ILocksService> LocksServices { get; }

        /// <summary> Holds the name of the default locks service to use. </summary>
        public static string DefaultLocksservice => typeof(BLE.LockItByScanServicePolling).FullName;

        /// <summary></summary>
       /// <param name="activeLockService">Name of active lock service implementation to use.</param>
        /// <param name="locksServices">Null for production (set of lock service implentations and some fake implementation will created) hash set of services for testing purposes. </param>
        public LocksServicesContainerMutable(
           string activeLockService,
            HashSet<ILocksService> locksServices)
        {
            LocksServices = new ServicesContainerMutable<ILocksService>(
                locksServices,
                activeLockService);
        }

        /// <summary> Active locks service.</summary>
        public ILocksService Active => LocksServices.Active; 

        /// <summary> Sets a lock service as active locks service by name. </summary>
        /// <param name="active">Name of the new locks service.</param>
        public void SetActive(string active) => LocksServices.SetActive(active);

        IEnumerator<string> IEnumerable<string>.GetEnumerator()
            => LocksServices.Select(x => x.GetType().FullName).GetEnumerator();
        IEnumerator IEnumerable.GetEnumerator()
            => LocksServices.GetEnumerator();

        public void SetTimeOut(TimeSpan connectTimeout)
        {
            foreach (var locksService in LocksServices)
            {
                locksService.TimeOut = new TimeOutProvider(new List<TimeSpan> { connectTimeout });
            }
        }
    }
}