// Log parser implementation
#include "log_parser.h"
#include <fstream>
#include <iostream>
#include <chrono>
#include <thread>

namespace mosis::test {

LogParser::LogParser(const std::filesystem::path& logPath)
    : m_logPath(logPath) {
}

void LogParser::SetLogPath(const std::filesystem::path& path) {
    m_logPath = path;
    Clear();
}

bool LogParser::Reload() {
    if (m_logPath.empty() || !std::filesystem::exists(m_logPath)) {
        return false;
    }

    std::ifstream file(m_logPath);
    if (!file.is_open()) {
        return false;
    }

    // Read all lines
    m_entries.clear();
    std::string line;
    while (std::getline(file, line)) {
        if (!line.empty()) {
            LogEntry entry;
            entry.message = line;
            m_entries.push_back(entry);
        }
    }

    return true;
}

void LogParser::Clear() {
    m_entries.clear();
    m_lastReadPosition = 0;
}

std::optional<LogEntry> LogParser::FindEntry(const std::string& pattern) const {
    // Search from newest to oldest
    for (auto it = m_entries.rbegin(); it != m_entries.rend(); ++it) {
        if (it->message.find(pattern) != std::string::npos) {
            return *it;
        }
    }
    return std::nullopt;
}

bool LogParser::Contains(const std::string& pattern) const {
    return FindEntry(pattern).has_value();
}

std::vector<LogEntry> LogParser::FindAllEntries(const std::string& pattern) const {
    std::vector<LogEntry> results;
    for (const auto& entry : m_entries) {
        if (entry.message.find(pattern) != std::string::npos) {
            results.push_back(entry);
        }
    }
    return results;
}

bool LogParser::WaitForEntry(const std::string& pattern, int timeoutMs) {
    auto startTime = std::chrono::steady_clock::now();

    while (true) {
        Reload();
        if (Contains(pattern)) {
            return true;
        }

        auto elapsed = std::chrono::steady_clock::now() - startTime;
        if (std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count() >= timeoutMs) {
            return false;
        }

        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}

std::vector<LogEntry> LogParser::GetLastEntries(size_t count) const {
    if (count >= m_entries.size()) {
        return m_entries;
    }

    std::vector<LogEntry> result;
    result.reserve(count);
    for (size_t i = m_entries.size() - count; i < m_entries.size(); ++i) {
        result.push_back(m_entries[i]);
    }
    return result;
}

} // namespace mosis::test
