use deno_core::v8;
use deno_core::ModuleSpecifier;
use serde::Serialize;
use std::cell::RefCell;
use std::thread;
use crate::colors;
#[derive(Debug, Default, Clone, Copy)]
pub enum WorkerLogLevel {
      Error = 1,
  Warn = 2,
  #[default]
  Info = 3,
  Debug = 4,
}
impl From<log::Level> for WorkerLogLevel {
  fn from(value: log::Level) -> Self {
    match value {
      log::Level::Error => WorkerLogLevel::Error,
      log::Level::Warn => WorkerLogLevel::Warn,
      log::Level::Info => WorkerLogLevel::Info,
      log::Level::Debug => WorkerLogLevel::Debug,
      log::Level::Trace => WorkerLogLevel::Debug,
    }
  }
}
#[derive(Clone)]
pub struct BootstrapOptions {
    pub args: Vec<String>,
  pub cpu_count: usize,
  pub log_level: WorkerLogLevel,
  pub enable_op_summary_metrics: bool,
  pub enable_testing_features: bool,
  pub locale: String,
  pub location: Option<ModuleSpecifier>,
    pub no_color: bool,
  pub is_tty: bool,
    pub unstable: bool,
    pub unstable_features: Vec<i32>,
  pub user_agent: String,
  pub inspect: bool,
  pub has_node_modules_dir: bool,
  pub maybe_binary_npm_command_name: Option<String>,
}
impl Default for BootstrapOptions {
  fn default() -> Self {
    let cpu_count = thread::available_parallelism()
      .map(|p| p.get())
      .unwrap_or(1);
    let runtime_version = env!("CARGO_PKG_VERSION");
    let user_agent = format!("Deno/{runtime_version}");
    Self {
      user_agent,
      cpu_count,
      no_color: !colors::use_color(),
      is_tty: colors::is_tty(),
      enable_op_summary_metrics: Default::default(),
      enable_testing_features: Default::default(),
      log_level: Default::default(),
      locale: "en".to_string(),
      location: Default::default(),
      unstable: Default::default(),
      unstable_features: Default::default(),
      inspect: Default::default(),
      args: Default::default(),
      has_node_modules_dir: Default::default(),
      maybe_binary_npm_command_name: None,
    }
  }
}
#[derive(Serialize)]
struct BootstrapV8<'a>(
    Option<&'a str>,
    bool,
    &'a [i32],
    bool,
    bool,
    bool,
    Option<&'a str>,
);
impl BootstrapOptions {
    pub fn as_v8<'s>(
    &self,
    scope: &mut v8::HandleScope<'s>,
  ) -> v8::Local<'s, v8::Value> {
    let scope = RefCell::new(scope);
    let ser = deno_core::serde_v8::Serializer::new(&scope);
    let bootstrap = BootstrapV8(
      self.location.as_ref().map(|l| l.as_str()),
      self.unstable,
      self.unstable_features.as_ref(),
      self.inspect,
      self.enable_testing_features,
      self.has_node_modules_dir,
      self.maybe_binary_npm_command_name.as_deref(),
    );
    bootstrap.serialize(ser).unwrap()
  }
}