#include "helpers.h"
#include "config.h"

#include <maps/libs/log8/include/log8.h>
#include <maps/libs/concurrent/include/scoped_guard.h>

#include <iomanip>

namespace maps::wiki::exporter {

void FormattedDuration::printTo(std::ostream& os) const
{
    using namespace std::chrono;
    auto millisLeft = millis_;

    const auto hs = duration_cast<hours>(millisLeft);
    millisLeft -= hs;
    const auto mins = duration_cast<minutes>(millisLeft);
    millisLeft -= mins;
    const auto secs = duration_cast<std::chrono::seconds>(millisLeft);
    millisLeft -= secs;
    os << hs.count()
       << ":" << std::setfill('0') << std::setw(2) << mins.count()
       << ":" << std::setfill('0') << std::setw(2) << secs.count()
       << "." << std::setfill('0') << std::setw(3) << millisLeft.count();
}

void cleanupOldDirs(
    const std::string& rootDir,
    const std::string& prefix,
    size_t numDirsToKeep)
{
    fs::path rootPath(rootDir);
    if (!fs::is_directory(rootPath)) {
        WARN() << "Export root directory does not exist: " << rootDir;
        return;
    }

    std::vector<fs::path> existingDirs;
    for (fs::directory_iterator itr(rootPath); itr != fs::directory_iterator(); ++itr) {
        auto& dir = itr->path();
        if (
            fs::is_directory(dir) &&
            dir.filename().string().starts_with(prefix)
        ) {
            existingDirs.emplace_back(fs::absolute(dir));
        }
    }

    std::sort(existingDirs.begin(), existingDirs.end());

    if (existingDirs.size() > numDirsToKeep) {
        for (size_t i = 0; i < existingDirs.size() - numDirsToKeep; ++i) {
            const auto& dir = existingDirs[i];
            try {
                INFO() << "Removing outdated dir: '" << dir << "'";
                fs::remove_all(dir);
            } catch (const std::exception& e) {
                WARN() << "Can not remove dir '" << dir << "': " << e.what();
            }
        }
    }
}

} // namespace maps::wiki::exporter
