//
// Copyright 2021, Jesús Pérez Lorenzo
//
// use core::fmt;
// use futures::lock::Mutex;
// use std::sync::Arc;

// use lazy_static::lazy_static;
// use once_cell::sync::Lazy;
// use std::sync::Arc;
// // use tokio::sync::Mutex;
// use parking_lot::RwLock;

use std::collections::HashMap;
// use serde::{Deserialize,Serialize};

use app_tools::{hash_from_data};

use crate::appenv::AppEnv;

#[derive(Clone, Debug, Default)]
pub struct AppData {
//  pub schema: Arc<Mutex<RootSchema>>,
  pub env: AppEnv,
//  pub vault: ServerVault,
  pub tera: tera::Tera,
  pub ctx: tera::Context,
}
impl AppData {
  /// Schema creation for `AppEnv`
  #[must_use]
  pub fn new(env: AppEnv) -> Self {
		let config = env.get_curr_websrvr_config();
    let templates_path = config.templates_path.to_owned();
    let default_module = config.default_module.to_owned();
//    let arc_schema = Arc::new(Mutex::from(schema));
    let mut tera = tera::Tera::default();
    let mut ctx = tera::Context::new();
    if env.info.can_do("templates") { 
      let templates = format!("{}/**/*", &templates_path);
      tera = match tera::Tera::new(templates.as_str()) {
        Ok(t) => {
          println!("WebServices Templates loaded from: {}", &templates_path);
          t
        }
        Err(e) => {
          println!("Error loading Templates {}: {} ", &templates, e);
          ::std::process::exit(1);
         //  tera::Tera::default()
        }
      };
      tera.autoescape_on(vec!["html", ".sql"]);
      let mut data_hash: HashMap<String, String> = HashMap::new();
      // let lang = String::from("es");
      let data_path = format!("{}/defaults.toml", &templates_path);
      match hash_from_data(&data_path, &mut ctx, &mut data_hash, true) {
        Ok(_) => {
          for (key, value) in &data_hash {  //.iter() {
            ctx.insert(key, value);
          }
          println!("Default WebServices templates module loaded from: {}", &data_path);
        }
        Err(e) => {
          println!("Error parsing data {}:{}", &data_path, e);
        }
      };
      AppData::load_modules(&env, &default_module,&mut ctx);
    }
    Self {
      env,
      tera,
      ctx,
    }
  }
  /// Load module info for templating if exists 
  pub fn load_modules(env: &AppEnv,target: &str, ctx: &mut tera::Context) {
    if let Some(module) = env.modules.get(target) {
      ctx.insert("name",&module.name);
      ctx.insert("title",&module.title);
      ctx.insert("key",&module.key);
      ctx.insert("dflt_lang",&module.dflt_lang);
      ctx.insert("template_path",&module.template_path);
      ctx.insert("logo_url",&module.logo_url);
      ctx.insert("css_url",&module.css_url);
      ctx.insert("bg_url",&module.bg_url);
      ctx.insert("color",&module.color);
      ctx.insert("main_color",&module.main_color);
      ctx.insert("captcha_color",&module.captcha_color);
      ctx.insert("main_bg",&module.main_bg);
      ctx.insert("manifesto",&module.manifesto);
    }
    //   if let Some(tbl_def) = module.as_table() {
    //     for (ky, val) in tbl_def {
    //       if let Some(value) = val.as_str() {
    //         // Insert into Tera ctx
    //         // println!("ky: [{}] -> val: [{}] ", ky, value);
    //         ctx.insert(ky, value);
    //       }
    //     }
    //   }
    // }
  }
}