Пофикси баги: #include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <windows.h>
#include <iomanip> // Для std::setw и std::left

using namespace std;

// Перечисление типов логов
enum class LogType {
    INFO,
    DEBUG,
    ERR,    // Изменено с ERROR на ERR
    WARN,
    UNKNOWN
};

// Функция для установки цвета текста и фона
void SetColor(int textColor, int bgColor) {
    HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(h, (bgColor << 4) | textColor);
}

// Функция для сброса цвета к стандартным
void ResetColor() {
    SetColor(7, 0); // Белый текст на черном фоне
}

// Функция для вывода текста с заданными цветами
void PrintWithColor(const string& text, int textColor, int bgColor) {
    SetColor(textColor, bgColor);
    cout << text;
}

// Функция для определения типа лога по ключевому слову
LogType GetLogType(const string& keyword) {
    if (keyword == "[INFO]") return LogType::INFO;
    if (keyword == "[DEBUG]") return LogType::DEBUG;
    if (keyword == "[ERROR]") return LogType::ERR;
    if (keyword == "[WARN]") return LogType::WARN;
    return LogType::UNKNOWN;
}

// Функция для получения строки ключевого слова
string GetLogKeyword(const string& str, size_t pos) {
    if (str.compare(pos, 6, "[INFO]") == 0) return "[INFO]";
    if (str.compare(pos, 7, "[DEBUG]") == 0) return "[DEBUG]";
    if (str.compare(pos, 7, "[ERROR]") == 0) return "[ERROR]";
    if (str.compare(pos, 6, "[WARN]") == 0) return "[WARN]";
    return "";
}

// Функция для обработки и вывода одной строки лога
void ProcessLogLine(const string& line, size_t maxLength,
    size_t& infoCount, size_t& debugCount,
    size_t& errCount, size_t& warnCount) {
    size_t pos = 0;
    size_t printedLength = 0;

    // Окрашиваем дату и время
    // Предполагаем формат: YYYY-MM-DD HH:MM:SS.mmm
    // Например: 2023-10-05 14:23:45.123
    string datetime;
    if (line.size() >= 23 &&
        line[4] == '-' && line[7] == '-' &&
        line[10] == ' ' && line[13] == ':' &&
        line[16] == ':' && line[19] == '.') {
        datetime = line.substr(0, 23);
        PrintWithColor(datetime, 8, 7); // Светло-серый текст на темно-сером фоне
        pos = 24; // Пропускаем пробел после даты
        printedLength += datetime.size() + 1;
    }
    else {
        // Если формат даты неверен, выводим без цвета
        datetime = "";
    }

    // Поиск первого ключевого слова
    size_t keywordPos = line.find_first_of("[", pos);
    while (keywordPos != string::npos) {
        // Выводим текст перед ключевым словом
        if (keywordPos > pos) {
            string text = line.substr(pos, keywordPos - pos);
            PrintWithColor(text, 15, 0); // Белый текст на стандартном фоне
            printedLength += text.size();
        }

        // Определяем тип лога
        string keyword = GetLogKeyword(line, keywordPos);
        LogType type = GetLogType(keyword);
        if (type != LogType::UNKNOWN) {
            switch (type) {
            case LogType::INFO:
                PrintWithColor("[INFO]", 15, 2); // Белый текст на зеленом фоне
                infoCount++;
                break;
            case LogType::DEBUG:
                PrintWithColor("[DEBUG]", 15, 1); // Белый текст на голубом фоне
                debugCount++;
                break;
            case LogType::ERR:
                PrintWithColor("[ERROR]", 15, 4); // Белый текст на красном фоне
                errCount++;
                break;
            case LogType::WARN:
                PrintWithColor("[WARN]", 15, 6); // Белый текст на желтом фоне
                warnCount++;
                break;
            default:
                PrintWithColor(keyword, 15, 0); // Стандартный вывод
                break;
            }
            pos = keywordPos + keyword.size();
            printedLength += keyword.size();
        }
        else {
            // Если ключевое слово не распознано, выводим как обычный текст
            PrintWithColor("[", 15, 0);
            pos = keywordPos + 1;
            printedLength += 1;
        }

        // Ищем следующее ключевое слово
        keywordPos = line.find_first_of("[", pos);
    }

    // Выводим оставшуюся часть строки
    if (pos < line.size()) {
        string text = line.substr(pos);
        PrintWithColor(text, 15, 0); // Белый текст на стандартном фоне
        printedLength += text.size();
    }

    // Добавляем отступы, если требуется
    if (printedLength < maxLength) {
        size_t paddingLength = maxLength - printedLength;
        string padding(paddingLength, ' ');
        PrintWithColor(padding, 15, 0); // Пробелы с стандартным фоном
    }

    ResetColor(); // Сброс цвета в стандартный
    cout << endl;
}

int main() {
    ifstream logFile("emulator.log");
    if (!logFile.is_open()) {
        cerr << "Error opening log file." << endl;
        system("pause");
        return 1;
    }

    // Читаем все строки в вектор и определяем максимальную длину
    vector<string> lines;
    string line;
    size_t maxLength = 0;
    while (getline(logFile, line)) {
        lines.push_back(line);
        if (line.length() > maxLength) {
            maxLength = line.length();
        }
    }
    logFile.close();

    // Устанавливаем фиксированную ширину для даты и времени
    const size_t datetimeWidth = 23; // Формат YYYY-MM-DD HH:MM:SS.mmm
    if (maxLength < datetimeWidth) {
        maxLength = datetimeWidth;
    }

    // Инициализируем счётчики
    size_t infoCount = 0;
    size_t debugCount = 0;
    size_t errCount = 0;
    size_t warnCount = 0;
    size_t totalCount = 0;

    // Обрабатываем каждую строку с учетом максимальной длины
    for (const auto& logLine : lines) {
        ProcessLogLine(logLine, maxLength, infoCount, debugCount, errCount, warnCount);
        totalCount++;
    }

    ResetColor(); // На всякий случай сбросим цвет

    // INFO
    PrintWithColor("INFO: ", 15, 0); // Белый текст на стандартном фоне
    SetColor(15, 2); // Белый текст на зеленом фоне
    cout << infoCount << endl;
    ResetColor();

    // DEBUG
    PrintWithColor("DEBUG: ", 15, 0); // Белый текст на стандартном фоне
    SetColor(15, 1); // Белый текст на голубом фоне
    cout << debugCount << endl;
    ResetColor();

    // ERROR
    PrintWithColor("ERROR: ", 15, 0); // Белый текст на стандартном фоне
    SetColor(15, 4); // Белый текст на красном фоне
    cout << errCount << endl;
    ResetColor();

    // WARN
    PrintWithColor("WARN: ", 15, 0); // Белый текст на стандартном фоне
    SetColor(15, 6); // Белый текст на желтом фоне
    cout << warnCount << endl;
    ResetColor();


    system("pause");
    return 0;
}