/**
 * @file dashboardapi_class.js
 * 
 * Permission is hereby granted to any person obtaining a copy of this software 
 * and associated documentation files (the "Software"), to use it for personal 
 * or non-commercial purposes, with the following restrictions:
 * 
 * 1. **No Copying or Redistribution**: The Software or any of its parts may not 
 *    be copied, merged, distributed, sublicensed, or sold without explicit 
 *    prior written permission from the author.
 * 
 * 2. **Commercial Use**: Any use of the Software for commercial purposes requires 
 *    a valid license, obtainable only with the explicit consent of the author.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, 
 * OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 * SOFTWARE.
 *
 * Ownership of this code remains solely with the original author. Unauthorized 
 * use of this Software is strictly prohibited.
 *
 * @summary A class for generating dynamic dashboards for system monitoring.
 * @description The Dashboardapi class facilitates the creation and customization 
 * of Grafana dashboards using JSON templates. It dynamically updates templating values 
 * based on provided measurement and bucket configurations, enabling seamless integration 
 * within monitoring environments.
 * @module dashboardapi_class
 * @exports Dashboardapi
 * @version 0.1.0
 * @since 0.1.0
 *
 * Author:
 * - Rene De Ren
 * Email:
 * - rene@thegoldenbasket.nl
 *
 * Future Enhancements:
 * - Incorporate additional dynamic templating capabilities.
 * - Add support for more customization options within dashboard configurations.
 */

//A class to interact and manipulate sampling machines

//load local dependencies
const EventEmitter = require('events');
const Logger = require('../../../generalfunctions/helper/logger');

//load all config modules
const defaultConfig = require('./dashboardapiConfig.json');
const ConfigUtils = require('../../../generalfunctions/helper/configUtils');

//load registration utility
const ChildRegistrationUtils = require('../../../generalfunctions/helper/childRegistrationUtils');

class Dashboardapi{
  /*-------------------               Construct and set vars               -------------------*/
  constructor(config={}){

    // basic setup  
    this.emitter = new EventEmitter();  // Own EventEmitter
    this.configUtils = new ConfigUtils(defaultConfig);
    this.config = this.configUtils.initConfig(config);

    this.child = {}        ; // object to hold child information so we know on what to subscribe

    // Init after config is set
    this.logger = new Logger(this.config.general.logging.enabled, this.config.general.logging.logLevel, this.config.general.name);

  }

  //how to handle children like the pump on a machine group node? Do we duplicate the information or fetch the names of the registered children en connect them 
  //to the dashboard?
  //this is a question that needs to be answered in the future.

  /*-------------------               FUNCTIONS               -------------------*/
  async getDashboard(softwareType){
    try {
      let response = await fetch(`http://localhost:1880/dashboardapi/config/${softwareType}.json`);
      if (!response.ok) {
          this.logger.error(`Failed to fetch dashboard template: ${response.statusText}`);
      }
      const jsonDashB = await response.json();
      return jsonDashB;
  } catch (error) {
      this.logger.error(`Failed to fetch dashboard template: ${error.message}`);
      
  }
  }
  //generate dashboards based on the childs connected
  async generateDashB(config) {
    //define file name
    const softwareType = config.functionality.softwareType;
    this.logger.debug(`Generating dashboard for ${softwareType}`);
    const jsonDashB = await this.getDashboard(softwareType);

    // Validate templating structure exists
    if (!jsonDashB.templating ||
        !Array.isArray(jsonDashB.templating.list) ||
        jsonDashB.templating.list.length < 3) {
      this.logger.error("Dashboard JSON templating structure is not as expected.");
      throw new Error("Invalid dashboard template structure");
    }
    
    const bucketName = "lvl2";
    const measurementName = config.general.name;

    // Set properties for a new dashboard
    jsonDashB.id = null;
    jsonDashB.uid = null;
    jsonDashB.title = measurementName;

    // Update measurement placeholder (using index 1)
    const measurementTpl = jsonDashB.templating.list[1];
    measurementTpl.current.text = measurementName;
    measurementTpl.current.value = measurementName;
    if (Array.isArray(measurementTpl.options) && measurementTpl.options.length > 0) {
      measurementTpl.options[0].text = measurementName;
      measurementTpl.options[0].value = measurementName;
    }
    measurementTpl.query = measurementName;

    // Update bucket placeholder (using index 2)
    const bucketTpl = jsonDashB.templating.list[2];
    bucketTpl.current.text = bucketName;
    bucketTpl.current.value = bucketName;
    if (Array.isArray(bucketTpl.options) && bucketTpl.options.length > 0) {
      bucketTpl.options[0].text = bucketName;
      bucketTpl.options[0].value = bucketName;
    }
    bucketTpl.query = bucketName;

    const output = {
      dashboard: jsonDashB,
      folderId: 0,
      overwrite: true
    };

    return output;
  }

} // end of class

module.exports = Dashboardapi;

/*
//import a child
const Child = require('../../../measurement/dependencies/measurement/measurement');
//const Child = require('../../../rotatingMachine/dependencies/machine/machine');

console.log(`Creating child...`);
const child = new Child(config={
  general:{
    name:"PT1",
    logging:{
      enabled:true,
      logLevel:"debug",
    },
  },
  functionality:{
    softwareType:"measurement",
  },
  asset:{
    type:"sensor",
    subType:"pressure",
  },
});

const d = new Dashboardapi();

testGen();

function testGen(){
  d.generateDashB(child.config).then((res)=>{
    console.log(res);
  });
}


//*/