using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Turing.Model
{
    //TODO: własny typ wyjątku i dodać do testów

    public class StanMaszyny
    {
        private string taśma;
        public char początkowyStanGłowicy;

        public StanMaszyny(string zawartość)
        {
            if (string.IsNullOrEmpty(zawartość)) throw new Exception("Taśma nie ma zawartości");
            if (!sprawdźTaśmę(zawartość)) throw new Exception("Taśma niepoprawna");
            taśma = wyodrębnijTaśmę(zawartość, out początkowyStanGłowicy);
        }

        private static bool sprawdźTaśmę(string taśma)
        {
            bool czyWszystkieZnakiSąLiterami = taśma.All(c => char.IsLetter(c));
            int liczbaMałychLiter = taśma.Count(c => char.IsLower(c));
            int liczbaDużychLiter = taśma.Count(c => char.IsUpper(c));
            bool złeLitery = taśma.Any(c => c == 'L' || c == 'R');
            bool czyTaśmaPoprawna = czyWszystkieZnakiSąLiterami && liczbaMałychLiter == 1 && liczbaMałychLiter + liczbaDużychLiter == taśma.Length && !złeLitery;
            return czyTaśmaPoprawna;
        }

        private static string wyodrębnijTaśmę(string zawartość, out char stanGłowicy)
        {
            //int indeksStanuGłowicy = zawartość.First(c => char.IsLower(c));
            stanGłowicy = zawartość.FirstOrDefault(c => c == 's');
            int indeksStanuGłowicy = zawartość.IndexOf(stanGłowicy);
            string taśma = zawartość.Remove(indeksStanuGłowicy, 1);
            return taśma;
        }

        public static (StanMaszyny Taśma, char StanGłowicy) Load(string ścieżkaPliku)
        {
            string zawartość = File.ReadAllText(ścieżkaPliku);
            StanMaszyny taśma = new StanMaszyny(zawartość);
            return (taśma, taśma.początkowyStanGłowicy);
        }

        public override string ToString()
        {
            return taśma;
        }

        public char this[int indeks] //indekser
        {
            get
            {
                return taśma[indeks];
            }
        }

        public char PoczątkowyStanGłowicy
        {
            get
            {
                return początkowyStanGłowicy;
            }
        }
    }
}
