using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace Framework.Sharing
{
    /// <summary>
    /// The service locator is a static class that holds a reference to 
    /// an instance of another object which should be provided prior to being
    /// used, if it is not a null version of that instance (which should
    /// be a child type of it) will be returned instead. 
    /// </summary>
    /// <typeparam name="ServiceType">The type of the service to locate</typeparam>
    /// <typeparam name="NullServiceType">The type of the null service to provide if the service can't be found</typeparam>
    public class ServiceLocator<ServiceType, NullServiceType> where NullServiceType : ServiceType, new()
    {
        protected static ServiceType service; // The service instance

        /// <summary>
        /// Returns the instance of the service, OR returns a null object 
        /// alternative if it cannot be found.
        /// </summary>
        /// <returns></returns>
        public static ServiceType Get()
        {
            if (service != null)
            {
                return service;
            }
            else
            {
                Debug.LogWarning("No service provider in scene");
                service = new NullServiceType();
                //throw new ServiceNotInstantiatedException("The service of type: " + typeof(T) + " is null and has not yet been instantiated. Provide it early on or change this implementation to use null objects.");
                return service;
            }
        }

        /// <summary>
        /// Method used to provide the service to this locator.
        /// </summary>
        /// <param name="service"></param>
        public static void Provide(ServiceType service)
        {
            ServiceLocator<ServiceType, NullServiceType>.service = service;
        }
    }
}
