// Maksims_Gutovs_PD_FS_b5
using System;
using System.Collections.Generic; // https://learn.microsoft.com/ru-ru/dotnet/api/system.collections.generic?view=net-9.0

class Program
{
    static void Main()
    {
        Folder c = new Folder("c:", null); // Izveido c: mapi
        Folder aktivaMape = c; // Aktiva mape ir sakuma c:

        while (true)
        {
            try
            //https://stackoverflow.com/questions/14973642/how-using-try-catch-for-exception-handling-is-best-practice
            {
                // Parada aktivas mapes celu
                Console.Write($"{GetCels(aktivaMape)}> ");
                string ievade = Console.ReadLine();
                string[] sadalits = ievade.Split(" ", 2, StringSplitOptions.RemoveEmptyEntries);

                if (sadalits.Length == 0) continue;

                string komanda = sadalits[0].ToLower();
                string args = (sadalits.Length > 1) ? sadalits[1] : "";

                switch (komanda)
                {
                    case "mkdir":
                        // Izveido jaunu mapi
                        if (!IsValidName(args)) break;

                        if (IrGlobalsNosaukums(c, args))
                        {
                            Console.WriteLine("Tads nosaukums jau eksiste citur!");
                            break;
                        }

                        if (aktivaMape.IrNosaukums(args))
                        {
                            Console.WriteLine("Objekts ar tadu nosaukumu jau eksiste!");
                            break;
                        }

                        if (aktivaMape.BernuSaraksts.Count >= 3)
                        {
                            Console.WriteLine("Mape nevar saturēt vairāk par 3 objektiem.");
                            break;
                        }

                        aktivaMape.BernuSaraksts.Add(new Folder(args, aktivaMape));
                        break;

                    case "create":
                        // Izveido jaunu failu
                        if (!IsValidName(args)) break;

                        if (IrGlobalsNosaukums(c, args))
                        {
                            Console.WriteLine("Tads nosaukums jau eksiste citur!");
                            break;
                        }

                        if (aktivaMape.IrNosaukums(args))
                        {
                            Console.WriteLine("Objekts ar tadu nosaukumu jau eksiste!");
                            break;
                        }

                        if (aktivaMape.BernuSaraksts.Count >= 3)
                        {
                            Console.WriteLine("Mape nevar saturēt vairāk par 3 objektiem.");
                            break;
                        }

                        aktivaMape.BernuSaraksts.Add(new File(args, aktivaMape));
                        break;

                    case "cd":
                        // Navigacija starp mapem
                        if (args == "..")
                        {
                            if (aktivaMape.Vecaks != null)
                                aktivaMape = aktivaMape.Vecaks;
                        }
                        else if (args == "/")
                            aktivaMape = c;
                        else
                        {
                            Objekts atrasts = aktivaMape.Meklet(args);
                            if (atrasts is Folder mape)
                                aktivaMape = mape;
                            else
                                Console.WriteLine("Mape nav atrasta.");
                        }
                        break;

                    case "rm":
                        // Dzes objektu
                        if (!aktivaMape.Dzest(args))
                            Console.WriteLine("Nav atrasts objekts.");
                        break;

                    case "dir":
                        // Parada mapes saturu
                        aktivaMape.Paradit();
                        break;

                    case "edit":
                        // Ievada saturu faila
                        Objekts redFile = aktivaMape.Meklet(args);
                        if (redFile is File f)
                        {
                            try
                            {
                                Console.WriteLine("Ievadi saturu:");
                                f.Saturs = Console.ReadLine();
                            }
                            catch
                            {
                                Console.WriteLine("Klaida redigejot failu.");
                            }
                        }
                        else
                            Console.WriteLine("Fails nav atrasts.");
                        break;

                    case "del":
                        // Dzes faila saturu
                        Objekts delFile = aktivaMape.Meklet(args);
                        if (delFile is File df)
                            df.Saturs = "";
                        else
                            Console.WriteLine("Fails nav atrasts.");
                        break;

                    case "exit":
                        // Iziet no programmas
                        return;
					case "by":
                        // Iziet no programmas
                        return;

                    default:
                        Console.WriteLine("Neatpazita komanda.");
                        break;
                }
            }
            catch (Exception ex)
            {
                // Apstrada visas kludas, kas var notikt komandu izpildes laika
                Console.WriteLine("ERROR: " + ex.Message);
            }
        }
    }

    // Veido pilnu celu no c: līdz aktīvajai mapei
    static string GetCels(Folder mape)
    {
        string cels = "";
        while (mape != null)
        {
            cels = "/" + mape.Nosaukums + cels;
            mape = mape.Vecaks;
        }
        return cels;
    }

    // Pārbauda vai nosaukums ir derīgs
    static bool IsValidName(string name)
    {
        if (string.IsNullOrWhiteSpace(name))
        {
            Console.WriteLine("Ievadi pareizu nosaukumu.");
            return false;
        }
        return true;
    }

    // Parbauda vai nosaukums eksiste jebkura vieta failu sistema
    static bool IrGlobalsNosaukums(Folder sakne, string nosaukums)
    {
        if (sakne.Nosaukums == nosaukums)
            return true;

        foreach (var b in sakne.BernuSaraksts)
        {
            if (b.Nosaukums == nosaukums)
                return true;

            if (b is Folder fm)
            {
                if (IrGlobalsNosaukums(fm, nosaukums))
                    return true;
            }
        }

        return false;
    }
}

// Pamatklase visiem objektiem (faili un mapes)
// info par abstract klasem https://www.w3schools.com/cs/cs_abstract.php un https://stackoverflow.com/questions/2570814/when-to-use-abstract-classes
abstract class Objekts
{
    public string Nosaukums;
    public Folder Vecaks;

    public Objekts(string nosaukums, Folder vecaks)
    {
        Nosaukums = nosaukums;
        Vecaks = vecaks;
    }

    public abstract void ParaditInfo(); // Virtuala metode, ko parraksta berni
}

// Mape - var saturet citus objektus
class Folder : Objekts
{
    public List<Objekts> BernuSaraksts = new List<Objekts>();

    public Folder(string nosaukums, Folder vecaks) : base(nosaukums, vecaks) { }

    public override void ParaditInfo()
    {
        Console.WriteLine("[MAPE] " + Nosaukums);
    }

    public bool IrNosaukums(string nosaukums)
    {
        foreach (var b in BernuSaraksts)
        {
            if (b.Nosaukums == nosaukums)
                return true;
        }
        return false;
    }

    public Objekts Meklet(string nosaukums)
    {
        foreach (var b in BernuSaraksts)
        {
            if (b.Nosaukums == nosaukums)
                return b;
        }
        return null;
    }

    public bool Dzest(string nosaukums)
    {
        var obj = Meklet(nosaukums);
        if (obj != null)
        {
            BernuSaraksts.Remove(obj);
            return true;
        }
        return false;
    }

    public void Paradit()
    {
        if (BernuSaraksts.Count == 0)
        {
            Console.WriteLine("[tuksa mape]");
            return;
        }

        foreach (var b in BernuSaraksts)
        {
            b.ParaditInfo();
        }
    }
}

// Fails - var saturet tekstu
class File : Objekts
{
    public string Saturs = "";

    public File(string nosaukums, Folder vecaks) : base(nosaukums, vecaks) { }

    public override void ParaditInfo()
    {
        Console.WriteLine("[FAILS] " + Nosaukums + (Saturs != "" ? " (saturs)" : ""));
    }
}
