// SPDX-License-Identifier: MPL-2.0
#include "vybuild.hpp"
#include "json.hpp"
#include "xxhash.h"
using namespace std;
vector<string> conditions={"folder_exists",
                           "folder_not_exists",
                           "folder_empty",
                           "folder_not_empty",
                           "cache_contains",
                           "cache_not_contains",
                           "var_exists",
                           "var_not_exists",
                           "var_equals",
                           "var_not_equals"};
bool vybuild::condition::evaluate_condition(const json &condition) {
  vybuild::actions::check_arg_string(condition,"condition");
  vybuild::actions::check_arg_vector_string(condition,"condition_args");
  string cond_name=condition["condition"].get<string>();
  if (condition["condition_variables"].get<bool>()) cond_name=vybuild::parser::string_vars(cond_name);
  if (find(conditions.begin(),conditions.end(),cond_name)==conditions.end()) {
    throw std::runtime_error("Invalid condition: "+cond_name);
  }
  vector<string> cond_args=condition["condition_args"].get<vector<string>>();
  if (condition["condition_args_variables"].get<bool>()) cond_args=vybuild::parser::vector_string_vars(cond_args);
  if (cond_name=="folder_exists") {
    if (cond_args.size()!=1) {
      throw std::runtime_error("Wrong amount of arguments for condition \""+cond_name+"\". Expected 1, got "+to_string(cond_args.size())+".");
    }
    return fs::exists(cond_args[0]);
  } else if (cond_name=="folder_not_exists") {
    if (cond_args.size()!=1) {
      throw std::runtime_error("Wrong amount of arguments for condition \""+cond_name+"\". Expected 1, got "+to_string(cond_args.size())+".");
    }
    return !fs::exists(cond_args[0]);
  } else if (cond_name=="folder_empty") {
    if (cond_args.size()!=1) {
      throw std::runtime_error("Wrong amount of arguments for condition \""+cond_name+"\". Expected 1, got "+to_string(cond_args.size())+".");
    }
    size_t nb_elements=0;
    for (const auto& element:fs::directory_iterator(cond_args[0])) {
      ++nb_elements;
    }
    return nb_elements==0;
  } else if (cond_name=="folder_not_empty") {
    if (cond_args.size()!=1) {
      throw std::runtime_error("Wrong amount of arguments for condition \""+cond_name+"\". Expected 1, got "+to_string(cond_args.size())+".");
    }
    size_t nb_elements=0;
    for (const auto& element:fs::directory_iterator(cond_args[0])) {
      ++nb_elements;
    }
    return nb_elements!=0;
  } else if (cond_name=="cache_contains") {
    if (cond_args.size()!=1) {
      throw std::runtime_error("Wrong amount of arguments for condition \""+cond_name+"\". Expected 1, got "+to_string(cond_args.size())+".");
    }
    string key=vybuild::cache::xxhash_to_string(XXH3_128bits(cond_args[0].c_str(),cond_args[0].size()));
    return vybuild::cache::cache_contains(key);
  } else if (cond_name=="cache_not_contains") {
    if (cond_args.size()!=1) {
      throw std::runtime_error("Wrong amount of arguments for condition \""+cond_name+"\". Expected 1, got "+to_string(cond_args.size())+".");
    }
    string key=vybuild::cache::xxhash_to_string(XXH3_128bits(cond_args[0].c_str(),cond_args[0].size()));
    return !vybuild::cache::cache_contains(key);
  } else if (cond_name=="var_exists") {
    if (cond_args.size()!=1) {
      throw std::runtime_error("Wrong amount of arguments for condition \""+cond_name+"\". Expected 1, got "+to_string(cond_args.size())+".");
    }
    auto globals_vars_name=vybuild::vars::get_global_variables_list();
    return (find(globals_vars_name.begin(),globals_vars_name.end(),cond_args[0])!=globals_vars_name.end());
  } else if (cond_name=="var_not_exists") {
    if (cond_args.size()!=1) {
      throw std::runtime_error("Wrong amount of arguments for condition \""+cond_name+"\". Expected 1, got "+to_string(cond_args.size())+".");
    }
    auto globals_vars_name=vybuild::vars::get_global_variables_list();
    return !(find(globals_vars_name.begin(),globals_vars_name.end(),cond_args[0])!=globals_vars_name.end());
  } else if (cond_name=="var_equals") {
    if (cond_args.size()!=2) {
      throw std::runtime_error("Wrong amount of arguments for condition \""+cond_name+"\". Expected 2, got "+to_string(cond_args.size())+".");
    }
    auto globals_vars_name=vybuild::vars::get_global_variables_list();
    if (find(globals_vars_name.begin(),globals_vars_name.end(),cond_args[0])==globals_vars_name.end()) throw std::runtime_error("Variable named \""+cond_args[0]+"\" doesn't exists.");
    string var_value=vybuild::vars::get_global_variable(cond_args[0]);
    return var_value==cond_args[1];
  } else if (cond_name=="var_not_equals") {
    if (cond_args.size()!=2) {
      throw std::runtime_error("Wrong amount of arguments for condition \""+cond_name+"\". Expected 2, got "+to_string(cond_args.size())+".");
    }
    auto globals_vars_name=vybuild::vars::get_global_variables_list();
    if (find(globals_vars_name.begin(),globals_vars_name.end(),cond_args[0])==globals_vars_name.end()) throw std::runtime_error("Variable named \""+cond_args[0]+"\" doesn't exists.");
    string var_value=vybuild::vars::get_global_variable(cond_args[0]);
    return var_value!=cond_args[1];
  }
  return false;
}
