#ifndef PHOTOCOMPRESSARCHIVER_H
#define PHOTOCOMPRESSARCHIVER_H

#include <atomic>
#include <condition_variable>
#include <cstdint>
#include <mutex>
#include <string>
#include <thread>
#include <vector>

#include <boost/filesystem.hpp>
#include <boost/regex.hpp>

// Alias the boost fs namespace to keep the code readable
namespace bfs = boost::filesystem;

const boost::regex JPEG_REGEX("^.+\\.(jpg)|(jpeg)$", boost::regex::icase);

class PhotoCompressArchiver
{
    public:
    
        PhotoCompressArchiver(const char* path, uint32_t num_cores);
        
        ~PhotoCompressArchiver();
        
        /**
         * Start processing
         */ 
        int execute();
        
        /**
         * Recursively find input files based on passed regex
         */ 
        void find_files(
            const bfs::path& dir_path, 
            const boost::regex& file_regex);
        
        /**
         * Fork and wait 
         */ 
        void fork_worker(uint32_t tid, std::vector<bfs::path>* file_sublist);
    
    private:
    
        const bfs::path m_path;             // top level path
        uint32_t m_num_cores;               // number of cores on the machine
        std::mutex m_output_mutex;          // output mutex
        
        uint32_t m_num_input_files;         // total number of input files found
        std::atomic<uint64_t> m_total_uncompressed_size;    // total uncompressed size of all images
        std::atomic<uint64_t> m_total_compressed_size;      // total compressed size of all images
        
        std::vector<bfs::path> m_file_list; // input file list (either images or compressed images)
        
        std::thread* p_finder_thread;             // file finder thread
        std::vector<std::thread*> m_worker_threads; // worker threads
};

#endif // PHOTOCOMPRESSARCHIVER_H
