#include <algorithm>
#include <chrono>
#include <filesystem>
#include <iostream>
#include <iterator>
#include <set>

namespace fs = std::filesystem;

int main() {
    // Answer 1
    auto print_last_write_time = [](std::filesystem::file_time_type const& ftime) {
        std::time_t time = std::chrono::system_clock::to_time_t(
            std::chrono::file_clock::to_sys(ftime));
        std::cout << "File write time is " << std::asctime(std::localtime(&time));
    };

    // Need to copy paths to vector, because directory_iterator is input type!
    // directory_iterator is a LegacyInputIterator that iterates over the directory_entry
    std::vector<fs::path> paths;
    std::transform(fs::directory_iterator(fs::current_path().string() + "/project"),
                   {},
                   std::back_inserter(paths),
                   [](const auto& entry) { return entry.path(); });

    const auto last_modify = std::min_element(
        cbegin(paths),
        cend(paths),
        [&](const auto& lhs, const auto& rhs) {
            const auto lhs_time = std::filesystem::last_write_time(lhs);
            const auto rhs_time = std::filesystem::last_write_time(rhs);
            return lhs_time > rhs_time;
        });

    std::cout << "Last modified file is: " << *last_modify << '\n';
    print_last_write_time(std::filesystem::last_write_time(*last_modify));

    // Answer 2
    auto time_compare = [](const fs::path& lhs, const fs::path& rhs) {
        const auto lhs_time = std::filesystem::last_write_time(lhs);
        const auto rhs_time = std::filesystem::last_write_time(rhs);
        return lhs_time == rhs_time ? lhs < rhs : lhs_time < rhs_time;
    };

    std::set<fs::path, decltype(time_compare)> lastModifiedFiles(
        fs::directory_iterator(fs::current_path() / "../project"),
        {},
        time_compare);

    std::cout << "files which were longest unmodified: \n";
    std::transform(std::cbegin(lastModifiedFiles),
                   std::next(std::cbegin(lastModifiedFiles), 3),
                   std::ostream_iterator<std::string>(std::cout),
                   [](const auto& path) {
                       std::stringstream ss;
                       std::time_t time = std::chrono::system_clock::to_time_t(
                           std::chrono::file_clock::to_sys(std::filesystem::last_write_time(path)));
                       ss << "File: " << path << " | last modify time: " << std::asctime(std::localtime(&time));

                       return ss.str();
                   });
}