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

//https://learn.microsoft.com/en-us/dotnet/api/system.io.directory
//https://learn.microsoft.com/en-us/dotnet/api/system.io.directory.getcurrentdirectory
//https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/selection-statements
//https://github.com/bobvanderlinden/sharpfilesystem/tree/master

public class FailuSistemasObjekts
{
    public string Nosaukums { get; set; }// Objekta nosaukums
    public FailuSistemasObjekts Vecaks { get; set; } // Norāde uz vecāka objektu
    public List<FailuSistemasObjekts> Berni { get; set; } // Saraksts ar bērnu objektiem
    public string Tips { get; set; }// "mape" vai "datne"
    public string Saturs { get; set; }// Datnes saturs (ja objekts ir datne)

    // Izveido jaunu failu sistēmas objektu
    public FailuSistemasObjekts(string nosaukums, string tips, FailuSistemasObjekts vecaks = null)
    {
        Nosaukums = nosaukums;
        Tips = tips;
        Vecaks = vecaks;
        Berni = new List<FailuSistemasObjekts>(); // Uztaisa tukšu bērnu sarakstu
        Saturs = ""; // Sākumā saturs ir tukšs
    }

    public virtual void Paradit()
    {
        if (Tips == "mape")
        {
            Console.WriteLine($"/[{Nosaukums}]");
        }
        else
        {
            Console.WriteLine($"~[{Nosaukums}]~");
        }
    }

    public virtual FailuSistemasObjekts Parvietoties()
    {
        if (Tips == "mape")
        {
            return this; // Atgriež pašreizējo mapi
        }
        else
        {
            Console.WriteLine("Nevar parvietoties");
            return null;
        }
    }

    public virtual void Dzest()
    {
        if (Tips == "mape" && Berni.Count > 0) // Pārbauda, vai mape nav tukša
        {
            Console.Write($"Vai tiesam grib dzest mapi '{Nosaukums}' un visus tas saturu? (y/n): ");
            string atbilde = Console.ReadLine().ToLower();
            if (atbilde == "y") // Apstiprina
            {
                Vecaks.Berni.Remove(this); // Noņem no vecāka bērnu sarakstu
                Console.WriteLine($"Mape '{Nosaukums}' un tas saturs ir izdzests");
            }
            else
            {
                Console.WriteLine("Dzesana atcelta");
            }
        }
        else
        {
            Vecaks.Berni.Remove(this); // Noņem no vecāka bērnu sarakstu
            Console.WriteLine($"Objekts '{Nosaukums}' ir izdzests");
        }
    }

    public virtual void Izveidot(string nosaukums, string tips)
    {
        if (Tips != "mape") // Pārbauda, vai pašreizējais objekts ir mape
        {
            Console.WriteLine("Nevar pievienot");
            return;
        }

        // Pārbauda, vai objekts ar šādu nosaukumu jau eksistē
        foreach (var berns in Berni)
        {
            if (berns.Nosaukums.Equals(nosaukums, StringComparison.OrdinalIgnoreCase))
            {
                Console.WriteLine($"Objekts ar nosaukumu '{nosaukums}' jau eksiste");
                return;
            }
        }

        // Izveido jaunu objektu un pievieno to bērnu sarakstam
        Berni.Add(new FailuSistemasObjekts(nosaukums, tips, this));
        Console.WriteLine($"Izveidots jauna {tips}: {nosaukums}");
    }
}

class Program
{
    static FailuSistemasObjekts currentDirectory;
    static FailuSistemasObjekts sakumaMape;

    static void Main(string[] args)
    {
        InicializetFailuSistemu();// Uztaisa failu sistēmu
        LietotajaSaskarne();// Sāk lietotāja saskarni
    }

    static void InicializetFailuSistemu()
    {
        sakumaMape = new FailuSistemasObjekts("c:", "mape"); // Izveido sakuma mapi
        currentDirectory = sakumaMape;
    }

    static void LietotajaSaskarne()
    {
        while (true)
        {
            try
            {
                // Parāda pašreizējo ceļu
                Console.Write($"{GetCurrentPath()}> ");
                string ievade = Console.ReadLine().Trim();
                
                // Ja ievade ir tukša, turpina ciklu
                if (string.IsNullOrEmpty(ievade)) continue;

                // Sadala ievadi atsevišķās komandās
                string[] komandas = ievade.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                string komanda = komandas[0].ToLower(); // Pārveido komandu uz mazajiem burtiem

                // Apstrādā komandu atkarībā no satura
                switch (komanda)
                {
                    case "exit":
                    case "by":
                        return; // Iziet no programmas

                    case "mkdir":
                        ApstradeMkdir(komandas); // Apstrādā mapju izveidi
                        break;

                    case "create":
                        ApstradeCreate(komandas); // Apstrādā datņu izveidi
                        break;

                    case "rm":
                        ApstradeRm(komandas); // Apstrādā mapju dzēšanu
                        break;

                    case "dir":
                        ApstradeDir(komandas); // Apstrādā direktorija satura apskatīšanos
                        break;

                    case "cd":
                        ApstradeCd(komandas); // Apstrādā direktorija maiņu
                        break;

                    case "edit":
                        ApstradeEdit(komandas); // Apstrādā datnes rediģēšanu
                        break;

                    case "del":
                        ApstradeDel(komandas); // Apstrādā datņu dzēšanu
                        break;

                    default:
                        Console.WriteLine($"Nezinama komanda: {komanda}");
                        break;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Kluda: {ex.Message}");
            }
        }
    }

    static string GetCurrentPath()
    {
        List<string> pathParts = new List<string>();
        FailuSistemasObjekts temp = currentDirectory;

        // Iet cauri visiem vecākiem, lai iegūtu pilno ceļu
        while (temp != null)
        {
            pathParts.Insert(0, temp.Nosaukums); // Pievieno nosaukumu saraksta sākumā
            temp = temp.Vecaks; // Pāriet uz vecāka objektu
        }

        return string.Join("/", pathParts); // Apvieno ceļa daļas ar "/"
    }

    static void ApstradeMkdir(string[] komandas)
    {
        if (komandas.Length < 2) // Pārbauda, vai ir norādīts mapes nosaukums
        {
            Console.WriteLine("Noradiet mapes nosaukumu");
            return;
        }

        // Apstrādā līdz 3 mapju nosaukumu vienā komandā
        for (int i = 1; i < komandas.Length && i < 4; i++)
        {
            currentDirectory.Izveidot(komandas[i], "mape"); // Izveido jaunu mapi
        }
    }

    static void ApstradeCreate(string[] komandas)
    {
        if (komandas.Length < 2) // Pārbauda, vai ir norādīts datnes nosaukums
        {
            Console.WriteLine("Noradiet datnes nosaukumu");
            return;
        }

        // Apstrādā līdz 3 datņu nosaukumus vienā komandā
        for (int i = 1; i < komandas.Length && i < 4; i++)
        {
            currentDirectory.Izveidot(komandas[i], "datne"); // Izveido jaunu datni
        }
    }

    static void ApstradeRm(string[] komandas)
    {
        if (komandas.Length < 2) // Pārbauda, vai ir norādīts mapes nosaukums
        {
            Console.WriteLine("Noradiet mapes nosaukumu");
            return;
        }

        // Apstrādā līdz 3 mapju nosaukumus vienā komandā
        for (int i = 1; i < komandas.Length && i < 4; i++)
        {
            bool found = false;
            
            // Meklē mapi pašreizējā direktorijā
            foreach (var berns in currentDirectory.Berni)
            {
                if (berns.Nosaukums.Equals(komandas[i], StringComparison.OrdinalIgnoreCase) && berns.Tips == "mape")
                {
                    berns.Dzest(); // Izsauc dzēšanas metodi
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                Console.WriteLine($"Mape '{komandas[i]}' nav atrasta");
            }
        }
    }

    static void ApstradeDir(string[] komandas)
    {
        if (komandas.Length > 1 && komandas[1] == ">") // Pārbauda, vai ir izvades pārvietošana uz datni
        {
            // dir > datne - izvada saturu datnē
            if (komandas.Length < 3)
            {
                Console.WriteLine("Noradiet datnes nosaukumu");
                return;
            }

            string datnesNosaukums = komandas[2];
            bool datneEksiste = false;
            FailuSistemasObjekts datne = null;

            // Meklē datni pašreizējā direktorijā
            foreach (var berns in currentDirectory.Berni)
            {
                if (berns.Nosaukums.Equals(datnesNosaukums, StringComparison.OrdinalIgnoreCase) && berns.Tips == "datne")
                {
                    datneEksiste = true;
                    datne = berns;
                    break;
                }
            }

            // Ja datne neeksistē, izveido jaunu
            if (!datneEksiste)
            {
                currentDirectory.Izveidot(datnesNosaukums, "datne");
                foreach (var berns in currentDirectory.Berni)
                {
                    if (berns.Nosaukums.Equals(datnesNosaukums, StringComparison.OrdinalIgnoreCase))
                    {
                        datne = berns;
                        break;
                    }
                }
            }

            // Sagatavo direktorija saturu
            string saturs = "";
            foreach (var berns in currentDirectory.Berni)
            {
                if (berns.Tips == "mape")
                {
                    saturs += $"/[{berns.Nosaukums}]\n";
                }
                else if (berns.Tips == "datne" && berns != datne)
                {
                    saturs += $"~[{berns.Nosaukums}]~\n";
                }
            }

            datne.Saturs = saturs; // Saglabā saturu datnē
            Console.WriteLine($"Direktorija saturs saglabats datne '{datnesNosaukums}'");
        }
        else
        {
            // Parasta dir komanda - rāda direktorija saturu
            if (currentDirectory.Berni.Count == 0)
            {
                Console.WriteLine("Direktorija ir tuksa");
            }
            else
            {
                foreach (var berns in currentDirectory.Berni)
                {
                    berns.Paradit(); // Izsauc objektu attēlošanu
                }
            }
        }
    }

    static void ApstradeCd(string[] komandas)
    {
        if (komandas.Length < 2) // Pārbauda, vai ir norādīts arguments
        {
            Console.WriteLine("Noradiet mapes nosaukumu vai '..'");
            return;
        }

        string mape = komandas[1];

        if (mape == "..") // Pārvietojas uz vecāka direktoriju
        {
            if (currentDirectory.Vecaks != null)
            {
                currentDirectory = currentDirectory.Vecaks;
            }
            else
            {
                Console.WriteLine("Jau esat sakuma mape");
            }
        }
        else if (mape == "/") // Pārvietojas uz sakuma direktoriju
        {
            currentDirectory = sakumaMape;
        }
        else
        {
            bool found = false;
            // Meklē norādīto mapi pašreizējā direktorijā
            foreach (var berns in currentDirectory.Berni)
            {
                if (berns.Nosaukums.Equals(mape, StringComparison.OrdinalIgnoreCase) && berns.Tips == "mape")
                {
                    currentDirectory = berns; // Pārvietojas uz norādīto mapi
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                Console.WriteLine("Nav tadas mapes");
            }
        }
    }

    static void ApstradeEdit(string[] komandas)
    {
        if (komandas.Length < 2) // Pārbauda, vai ir norādīts datnes nosaukums
        {
            Console.WriteLine("Noradiet datnes nosaukumu");
            return;
        }

        string datnesNosaukums = komandas[1];
        bool found = false;

        // Meklē datni pašreizējā direktorijā
        foreach (var berns in currentDirectory.Berni)
        {
            if (berns.Nosaukums.Equals(datnesNosaukums, StringComparison.OrdinalIgnoreCase) && berns.Tips == "datne")
            {
                Console.WriteLine($"Redige datni: {datnesNosaukums}");
                Console.WriteLine("--- Saturs ---");
                Console.WriteLine(berns.Saturs); // Parāda datnes saturu
                Console.WriteLine("--------------");
                found = true;
                break;
            }
        }

        if (!found)
        {
            Console.WriteLine($"Datne '{datnesNosaukums}' nav atrasta");
        }
    }

    static void ApstradeDel(string[] komandas)
    {
        if (komandas.Length < 2) // Pārbauda, vai ir norādīts datnes nosaukums
        {
            Console.WriteLine("Noradiet datnes nosaukumu");
            return;
        }

        // Apstrādā līdz 3 datņu nosaukumus vienā komandā
        for (int i = 1; i < komandas.Length && i < 4; i++)
        {
            bool found = false;
            // Meklē datni pašreizējā direktorijā
            foreach (var berns in currentDirectory.Berni)
            {
                if (berns.Nosaukums.Equals(komandas[i], StringComparison.OrdinalIgnoreCase) && berns.Tips == "datne")
                {
                    berns.Dzest(); // Izsauc dzēšanas metodi
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                Console.WriteLine($"Datne '{komandas[i]}' nav atrasta");
            }
        }
    }
}