using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using SharpCompress.Readers;
using SharpCompress.Common;

namespace Log_File_Remover
{
    class Program
    {
        static void Main(string[] args)
        {
            // console encoding
            Console.OutputEncoding = Encoding.UTF8;

            // шапка + инструкция
            string[] head = new string[]
            {
            "****************************************************************",
            "  Автор: https://t.me/adamusfb",
            "****************************************************************",
            "Как пользоваться:",
            "- Создайте отдельную директорию в любом месте. Важно чтобы в названии папки не было пробелов!",
            "- Загрузите в созданную папку материал в папках/zip/rar",
            "- Запустите программу и укажите все требуемые данные",
            Environment.NewLine,
            "Возможности:",
            "- Автораспаковка архивов в форматах zip/rar",
            "- Удаление файлов с разрешениями отличающимися от .txt",
            "- Удаление файлов без содержания указанного ключевика",
            "- Удаление пустых директорий и поддерикторий",
            "- Создание отдельных файлов с паролями по ключевику (good_passwords.txt)",
            "- Создание отдельных файлов с куками по ключевику (good_cookies.txt)",
            Environment.NewLine,
            "Примечания:",
            "- Будьте внимательны, когда указываете путь к папке! Укажите путь к рабочему столу - сотрете все файлы на нем без возможности восстановления",
            "- Потренеруйтесь на отработанном материале/копируйте свежий в отдельную папку. Научитесь сначала работать с инструментом",
            "- Автор не несет ответственность за вашу невнимательность при работе с программой",
            "- Автор не обязан оказывать какую-либо информационную поддержку по поводу работы программы",
            "****************************************************************",
            Environment.NewLine
            };

            foreach (string msg in head)
                Console.WriteLine(msg);

            // входные данные
            Console.WriteLine("Путь к папке:");
            string folder_path = Console.ReadLine();
            Console.WriteLine("Какой ключ должен быть в файле (прим. facebook):");
            string key = Console.ReadLine().ToLower();
            string log_path = Path.Combine(folder_path, "log.txt");
            bool clear_strokes = false;
            bool clear_cookies = false;
            bool leave_only_goods = false;
            string fp_name = "password";
            int str_num = 4;

            // вопросы
            do
            {
                Console.WriteLine("Очистить файл с паролями и оставить только ключевик? Будет записано в файл good_passwords.txt (y/n)");
                string selecter = Console.ReadLine();

                if (selecter == "n")
                    break;

                if (selecter == "y")
                {
                    clear_strokes = true;
                    Console.WriteLine("Как называется файл с паролями (прим. Passwords):");
                    fp_name = Console.ReadLine().ToLower();
                    Console.WriteLine("Количество строк для сохранения после ключа (включая ключ):");
                    str_num = Convert.ToInt32(Console.ReadLine());
                }
            }
            while (!clear_strokes);

            do
            {
                Console.WriteLine("Оставить только нужные куки? Будет записано в файл good_cookies.txt (y/n)");
                string selecter = Console.ReadLine();

                if (selecter == "n")
                    break;

                if (selecter == "y")
                    clear_cookies = true;
            }
            while (!clear_cookies);

            if (clear_strokes && clear_cookies)
                do
                {
                    Console.WriteLine("Оставить файлы только с пометкой в названии \"good_\"? (y/n)");
                    string selecter = Console.ReadLine();

                    if (selecter == "n")
                        break;

                    if (selecter == "y")
                        leave_only_goods = true;
                }
                while (!leave_only_goods);

            Console.WriteLine("****************************************************************");

            // инициализация класса
            LfrClass lfr = new LfrClass();

            lfr.ArchiveUnpacker(folder_path);
            lfr.DeleteOtherFiles(folder_path);
            lfr.DeleteNoKeyFiles(folder_path, key);
            if (clear_strokes)
                lfr.CreatePasswords(folder_path, fp_name, key, str_num);
            if (clear_cookies)
                lfr.CreateCookies(folder_path, key);
            if (leave_only_goods)
                lfr.LeaveOnlyGoods(folder_path);
            lfr.DeleteEmptyDirectory(folder_path);

            Console.WriteLine(Environment.NewLine);
            Console.WriteLine("****************************************************************");

            Thread.Sleep(10 * 1000);
        }

        public class LfrClass
        {
            // автоматическая распаковка архивов
            public void ArchiveUnpacker(string folder_path)
            { 
                var archives = Directory.GetFiles(folder_path, "*", SearchOption.AllDirectories).Where(f => f.EndsWith(".zip") || f.EndsWith(".rar")).ToArray();

                // progress block
                const int percent = 100;
                int count = archives.Count();
                var result = 0.0;

                if (count > 0)
                {
                    Console.WriteLine("Распаковка архивов:");
                    ConsoleUtility.WriteProgressBar(0);
                }

                foreach (var archive in archives)
                {
                    string path = Path.Combine(folder_path, Path.GetFileNameWithoutExtension(archive));
                    Directory.CreateDirectory(path);

                    using (Stream stream = File.OpenRead(archive))
                    {
                        try
                        {
                            var reader = ReaderFactory.Open(stream);
                            while (reader.MoveToNextEntry())
                                if (!reader.Entry.IsDirectory)
                                    reader.WriteEntryToDirectory(path, new ExtractionOptions() { ExtractFullPath = true, Overwrite = true });
                        }
                        catch (Exception){};
                    }

                    result += (float)percent / count;
                    ConsoleUtility.WriteProgressBar(Convert.ToInt32(result), true);
                    File.Delete(archive);
                }
            }

            // удаление других файлов (отличных от txt)
            public void DeleteOtherFiles(string folder_path)
            {
                var other_files = Directory.GetFiles(folder_path, "*.*", SearchOption.AllDirectories).Where(x => !x.EndsWith(".txt", StringComparison.OrdinalIgnoreCase)).ToArray();

                // progress block
                const int percent = 100;
                int count = other_files.Count();
                var result = 0.0;

                if (count > 0)
                {
                    Console.WriteLine(Environment.NewLine);
                    Console.WriteLine("Удаление не *.txt файлов:");
                    ConsoleUtility.WriteProgressBar(0);
                }

                foreach (string file in other_files)
                {
                    File.Delete(file);

                    result += (float)percent / count;
                    ConsoleUtility.WriteProgressBar(Convert.ToInt32(result), true);
                };
            }

            // удаление файлов не содержащих ключевого слова
            public void DeleteNoKeyFiles(string folder_path, string key)
            {
                var files = Directory.GetFiles(folder_path, "*.txt", SearchOption.AllDirectories);

                // progress block
                const int percent = 100;
                int count = files.Count();
                var result = 0.0;

                if (count > 0)
                {
                    Console.WriteLine(Environment.NewLine);
                    Console.WriteLine("Удаление файлов не содержащих ключевика "+key+":");
                    ConsoleUtility.WriteProgressBar(0);
                }

                foreach (string file in files)
                {
                    string text = File.ReadAllText(file);

                    if (!text.Contains(key))
                        File.Delete(file);

                    result += (float)percent / count;
                    ConsoleUtility.WriteProgressBar(Convert.ToInt32(result), true);
                };
            }

            // удаление пустых папок в директории
            public void DeleteEmptyDirectory(string folder_path)
            {
                var directories = Directory.GetDirectories(folder_path, "*", SearchOption.AllDirectories);

                // progress block
                const int percent = 100;
                int count = directories.Count();
                var result = 0.0;

                if (count > 0)
                {
                    Console.WriteLine(Environment.NewLine);
                    Console.WriteLine("Удаление пустых директорий:");
                    ConsoleUtility.WriteProgressBar(0);
                }

                foreach (var directory in directories)
                {
                    try
                    {
                        if (Directory.GetFiles(directory, "*", SearchOption.AllDirectories).Length == 0)
                            Directory.Delete(directory, true);
                    }
                    catch (Exception) { }

                    result += (float)percent / count;
                    ConsoleUtility.WriteProgressBar(Convert.ToInt32(result), true);
                }
            }

            // создание отдельного файла с нужными паролями good_passwords.txt
            public void CreatePasswords(string folder_path, string fp_name, string key, int str_num)
            {
                var passwords = Directory.GetFiles(folder_path, "*.txt", SearchOption.AllDirectories);

                // progress block
                const int percent = 100;
                int count = passwords.Count();
                var result = 0.0;

                if (count > 0)
                {
                    Console.WriteLine(Environment.NewLine);
                    Console.WriteLine("Создание отдельных файлов с паролями good_"+ fp_name+":");
                    ConsoleUtility.WriteProgressBar(0);
                }

                foreach (var password in passwords)
                {
                    if (Path.GetFileName(password).ToLower().Contains(fp_name))
                    {
                        string[] lines = File.ReadAllLines(password);
                        List<string> g_lines = new List<string> { };

                        for (int i1 = 0; i1 < lines.Length; i1++)
                        {
                            if (lines[i1].Contains(key))
                            {
                                int counter = 0;

                                for (int i2 = 0; i2 < str_num; i2++)
                                {
                                    string str = lines[i1 + counter];

                                    g_lines.Add(str);
                                    counter += 1;
                                }

                                g_lines.Add(Environment.NewLine);
                            }
                        }

                        File.WriteAllLines(Path.Combine(Path.GetDirectoryName(password), "good_" + fp_name + ".txt"), g_lines);
                    }

                    result += (float)percent / count;
                    ConsoleUtility.WriteProgressBar(Convert.ToInt32(result), true);
                }
            }

            // создание отдельного файла с нужными паролями good_cookies.txt
            public void CreateCookies(string folder_path, string key)
            {
                var cookies = Directory.GetFiles(folder_path, "*.txt", SearchOption.AllDirectories);

                // progress block
                const int percent = 100;
                int count = cookies.Count();
                var result = 0.0;

                if (count > 0)
                {
                    Console.WriteLine(Environment.NewLine);
                    Console.WriteLine("Создание отдельных файлов с куками good_cookies:");
                    ConsoleUtility.WriteProgressBar(0);
                }

                foreach (string cookie in cookies)
                {
                    string text = File.ReadAllText(cookie);
                    Regex newReg = new Regex("\t", RegexOptions.IgnoreCase);
                    MatchCollection matches = newReg.Matches(text);

                    if (matches.Count > 50)
                    {
                        List<string> a_cookies = new List<string> { };
                        List<string> g_cookies = new List<string> { };

                        a_cookies.AddRange(File.ReadAllLines(cookie));

                        foreach (string line in a_cookies)
                            if (line.ToLower().Contains(key))
                            {
                                Regex regex = new Regex("\t");
                                string[] bits = regex.Split(line);

                                if (bits[0].Contains(key))
                                    g_cookies.Add(line);
                            }

                        if (g_cookies.Count > 2)
                            File.WriteAllLines(Path.Combine(Path.GetDirectoryName(cookie), "good_" + Path.GetFileNameWithoutExtension(cookie) + ".txt"), g_cookies);
                    }

                    result += (float)percent / count;
                    ConsoleUtility.WriteProgressBar(Convert.ToInt32(result), true);
                }
            }

            public void LeaveOnlyGoods(string folder_path)
            {
                var goods = Directory.GetFiles(folder_path, "*", SearchOption.AllDirectories);

                // progress block
                const int percent = 100;
                int count = goods.Count();
                var result = 0.0;

                if (count > 0)
                {
                    Console.WriteLine(Environment.NewLine);
                    Console.WriteLine("Удаление файлов не содержащих \"good_\":");
                    ConsoleUtility.WriteProgressBar(0);
                }

                foreach (var good in goods)
                {
                    string file_name = Path.GetFileNameWithoutExtension(good).ToLower();

                    if (!file_name.Contains("good"))
                        File.Delete(good);

                    result += (float)percent / count;
                    ConsoleUtility.WriteProgressBar(Convert.ToInt32(result), true);
                }
            }
        }

        static class ConsoleUtility
        {
            const char _block = '■';
            const string _back = "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
            const string _twirl = "-\\|/";
            public static void WriteProgressBar(int percent, bool update = false)
            {
                if (update)
                    Console.Write(_back);
                Console.Write("[");
                var p = (int)((percent / 10f) + .5f);
                for (var i = 0; i < 10; ++i)
                {
                    if (i >= p)
                        Console.Write(' ');
                    else
                        Console.Write(_block);
                }
                Console.Write("] {0,3:##0}%", percent);
            }
            public static void WriteProgress(int progress, bool update = false)
            {
                if (update)
                    Console.Write("\b");
                Console.Write(_twirl[progress % _twirl.Length]);
            }
        }
    }
}