#include <iostream>
#include <string>
#include <fstream>
#include <filesystem>
#include <vector>
#include <algorithm>
#include <memory>

#include <bobcat/exception>
#include <bobcat/string>
#include <bobcat/glob>

using namespace std;
using namespace FBB;

namespace fs = filesystem;

char const usage[] = R"(
#ifndef SPCH_ + the next #endif lines found in .ih files located in the
current directory and in subdirectories are removed.
Specify files to skip as command-line arguments.

)";

vector<string> skip;

error_code ec;

void cleanup(string const &target)
{
    string dest{ target + ".mod" };
    ifstream in = Exception::factory<ifstream>(target);
    ofstream out = Exception::factory<ofstream>(dest);

    string line;
    bool hit;
    while (getline(in, line))
    {
                                            // found the SPCH_ line
        if (String::trim(line).find("#ifndef SPCH_") == 0)    
        {
            hit = true;
            break;
        }
        out << line << '\n';                // no SPCH_: line to out
    }

    if (not hit)
    {
        fs::remove(dest, ec);               // rm the partially written out
        return;
    }

    while (getline(in, line))               // read until #endif
    {
        if (String::trim(line).find("#endif") == 0) // found it
            break;
        out << line << '\n';                // cp non-#endif lines
    }
    out << in.rdbuf();                      // cp the remaining lines
    out.close();                            // flush the buffer
    fs::rename(dest, target);
    cout << target << '\n';                 // the name of the modified file
}

void check(char const *entry)
{
    if (find(skip.begin(), skip.end(), entry) == skip.end())
        cleanup(entry);
}

void glob(char const *pattern)
{
    unique_ptr<Glob> gp;
    try
    {
        gp.reset(new  Glob{Glob::REGULAR_FILE, pattern });
    }
    catch (...)     // glob: no hits
    {
        return;
    }

    for (char const *entry: *gp)
        check(entry);
}
    
int main(int argc, char **argv)
try
{
    if (argc == 2 and string{ "-h" } == argv[1])
    {
        cout << usage;
        return 0;
    }

    for (int idx = 1; idx != argc; ++idx)
        skip.push_back(argv[idx]);

    glob("*/*.ih");
    glob("*.ih");


//        check(entry);

//    string line;
//    while (getline(classes, line))
//    {
//        if (                                // skip empty / comment lines
//            line = String::trim(line);      // of argv[0]
//            line.empty() or line.find_first_of("#/") == 0
//        )
//            continue;
//
//        string target = line + '/' + line + ".ih";
//
//        if (fs::exists(target, ec))
//            cleanup(target);
//    }
//
//    for (int idx = 2; idx != argc; ++idx)
//        cleanup(argv[idx]);
}
catch (exception const &exc)
{
    cerr << "noifdef: " << exc.what() << '\n';
    return 1;
}



