using System;
using System.Collections.Generic;
using System.IO;

namespace _158326_Week_7_Singletons
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("158.326 Software Architecture");
            Console.WriteLine("\tWeek 7 - Singleton Design Pattern");
            Console.WriteLine("\tSingletons are instanced classes that can have only 0 or 1 instances of that class in existance in the application (Multitons are a variant that restricts the maximum number of instances)");
            Console.WriteLine("\nCompany:");
            for (int i = 0; i < 10; i++)
            {
                try
                {
                    Company instanceOfCompany = Company.GetCompany();
                    Console.WriteLine(instanceOfCompany.ShowDetails());
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
            Console.WriteLine("\nFileSingleton:");
            for (int i = 0; i < 10; i++)
            {
                try
                {
                    FileSingleton instanceOfCompany = FileSingleton.GetInstance(i);
                    Console.WriteLine(instanceOfCompany.ShowDetails());
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
            for (int i = 100; i < 110; i++)
            {
                try
                {
                    FileSingleton instanceOfCompany = FileSingleton.GetInstance(i);
                    Console.WriteLine(instanceOfCompany.ShowDetails());
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
            Console.WriteLine("\nCompany:");
            for (int i = 0; i < 10; i++)
            {
                try
                {
                    Company instanceOfCompany = Company.GetCompany();
                    Console.WriteLine(instanceOfCompany.ShowDetails());
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }

        }
    }

    /// <summary>
    /// Represents a singleton file stream; useful for logs etc., where access to a specific file should be performed singularly
    /// (don't open multiple streams on the same file)
    /// </summary>
    sealed class FileSingleton
    {
        /// <summary>
        /// Store the instance in a private, static variable
        /// </summary>
        private static FileSingleton instance;
        private string _name;

        /// <summary>
        /// Path of the file to open
        /// </summary>
        //public static Uri FilePath { get; set; } = new Uri("\\log.txt", UriKind.Relative); // Opens exactly one file stream on log.txt and will always return that stream

        // We can define instance variables here:
       // public FileStream OpenedFileStream { get; set; } // Calling FileSingleton.GetInstance().OpenedFileStream will always return this object


        // We can also define  

        /// <summary>
        /// The default constructor must be implemented, and as private so only functions in this class may call it
        /// This restricts the creation of this instance to local methods, so by restricting constructor calls
        /// to GetInstance(), we can ensure that only one instance is created
        /// </summary>
        private FileSingleton(int i) 
        {
            _name = i.ToString();
        }

        
        /// <summary>
        /// Gets the initialised instance of FileSingleton
        /// </summary>
        /// <returns></returns>
public static FileSingleton GetInstance(int i)
{
    if (instance is null)
    {
        instance = new FileSingleton(i);
    }
    return instance;
}

        public string ShowDetails()
        {
            return _name;
        }
    }

    public sealed class Company
    {
        private string _name;
        private static Company _company;
        private bool _legalInstance;
        private List<string> _listEmployee;

        private Company()
        {
            if (_company == null)
            {
                _company = this;
                _name = "test";
                _legalInstance = true;
            }
            else
            {
                _legalInstance = false;
            }
            
        }

        public static Company GetCompany()
        {
            return new Company();
        }

        public string ShowDetails()
        {
            if (_legalInstance)
            {
                return _name;
            }
            else
            {
                throw new ApplicationException("Null Object");
            }
        }
    }
}
