#include "camera_service.h"

#include <chrono>
#include <cctype>
#include <csignal>
#include <cstdlib>
#include <dirent.h>
#include <fstream>
#include <iostream>
#include <string>
#include <sys/types.h>
#include <thread>
#include <unistd.h>
#include <vector>

namespace driver {
namespace camera {
namespace {

std::vector<pid_t> find_processes(const std::string &name){
    std::vector<pid_t> result;
    DIR *proc = opendir("/proc");
    if(!proc) return result;

    while(dirent *entry = readdir(proc)){
        if(!std::isdigit(static_cast<unsigned char>(entry->d_name[0]))) continue;
        char *end = nullptr;
        const long value = std::strtol(entry->d_name, &end, 10);
        if(!end || *end != '\0' || value <= 0 || value == getpid()) continue;

        std::ifstream comm(std::string("/proc/") + entry->d_name + "/comm");
        std::string process_name;
        if(std::getline(comm, process_name) && process_name == name)
            result.push_back(static_cast<pid_t>(value));
    }
    closedir(proc);
    return result;
}

} // namespace

bool stop_firmware_service(){
    const auto processes = find_processes("rkipc");
    if(processes.empty()) return true;

    std::cerr << "[camera] stopping firmware rkipc service\n";
    for(pid_t pid : processes) kill(pid, SIGTERM);
    for(int retry = 0; retry < 50; ++retry){
        if(find_processes("rkipc").empty()) return true;
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    std::cerr << "[camera] rkipc did not release the camera\n";
    return false;
}

} // namespace camera
} // namespace driver
