#include "BashrcEditor.hpp"
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <algorithm>
#include <filesystem>
#include <iostream>
#include "DropshellScriptManager.hpp"

namespace dropshelltool
{
    const std::filesystem::path DROPSHELL_RC_PATH = std::filesystem::path(std::getenv("HOME")) / ".bashrc_dropshell_tool";
    static const std::filesystem::path BASHRC_PATH = std::filesystem::path(std::getenv("HOME")) / ".bashrc";

    std::string removeWhitespace(const std::string &s)
    {
        std::string out;
        for (char c : s)
        {
            if (!isspace(static_cast<unsigned char>(c)))
                out += c;
        }
        return out;
    }

    static constexpr const char *BLOCK_START = "#---DROPSHELL-TOOL-START---";
    static constexpr const char *BLOCK_END = "#---DROPSHELL-TOOL-END---";

    BashrcEditor::BashrcEditor()
    {
    }

    bool BashrcEditor::hasSourceLine() const
    {
        std::ifstream infile(BASHRC_PATH);
        if (!infile)
            return false;
        std::string line;
        bool inBlock = false;
        const std::string blockStart = removeWhitespace(BLOCK_START);
        const std::string blockEnd = removeWhitespace(BLOCK_END);
        const std::string target = "source \"" + DROPSHELL_RC_PATH.string() + "\"";
        while (std::getline(infile, line))
        {
            std::string trimmed = removeWhitespace(line);
            if (trimmed == blockStart)
            {
                return true;
            }
        }
        return false;
    }

    void BashrcEditor::addSourceLine()
    {
        std::ifstream infile(BASHRC_PATH);
        std::vector<std::string> lines;
        std::string line;
        bool inBlock = false;
        const std::string blockStart = removeWhitespace(BLOCK_START);
        const std::string blockEnd = removeWhitespace(BLOCK_END);
        while (std::getline(infile, line))
        {
            std::string trimmed = removeWhitespace(line);
            if (trimmed == blockStart)
            {
                inBlock = true;
                continue;
            }
            if (trimmed == blockEnd)
            {   
                inBlock = false;
                continue;
            }
            if (!inBlock)
            {
                lines.push_back(line);
            }
        }
        infile.close();
        lines.push_back(BLOCK_START);
        lines.push_back("source \"" + DROPSHELL_RC_PATH.string() + "\"");
        lines.push_back(BLOCK_END);
        std::ofstream outfile(BASHRC_PATH, std::ios::trunc);
        for (const auto &l : lines)
        {
            outfile << l << "\n";
        }

        outfile.close();

        if (!std::filesystem::exists(DROPSHELL_RC_PATH))
        {
            DropshellScriptManager scriptManager;
            scriptManager.ensureExists();
        }
    }

    void BashrcEditor::removeSourceLine()
    {
        std::ifstream infile(BASHRC_PATH);
        std::vector<std::string> lines;
        std::string line;
        bool inBlock = false;
        const std::string blockStart = removeWhitespace(BLOCK_START);
        const std::string blockEnd = removeWhitespace(BLOCK_END);
        while (std::getline(infile, line))
        {
            std::string trimmed = removeWhitespace(line);
            if (trimmed == blockStart)
            {
                inBlock = true;
                continue;
            }
            if (trimmed == blockEnd)
            {
                inBlock = false;
                continue;
            }
            if (!inBlock)
            {
                lines.push_back(line);
            }
        }
        infile.close();
        std::ofstream outfile(BASHRC_PATH, std::ios::trunc);
        for (const auto &l : lines)
        {
            outfile << l << "\n";
        }
    }

}