const { Callbacks, getJSON, get } = require("jquery");

require([
  "jquery",
  "underscore",
  "splunkjs/mvc",
  "splunkjs/mvc/utils",
  "splunkjs/mvc/searchcontrolsview",
  "splunkjs/mvc/searchmanager",
  "splunkjs/mvc/postprocessmanager",
  "splunkjs/mvc/dropdownview",
  "splunkjs/mvc/multidropdownview",
  "splunkjs/mvc/tableview",
  "splunkjs/mvc/eventsviewerview",
  "splunkjs/mvc/textinputview",
  "splunkjs/mvc/singleview",
  "splunkjs/mvc/chartview",
  "splunkjs/mvc/resultslinkview",
  "splunkjs/mvc/simplexml/searcheventhandler",
  "splunkjs/mvc/visualizationregistry",
  "splunkjs/mvc/simpleform/input/linklist",
  "splunkjs/mvc/simpleform/input/text",
  "splunkjs/mvc/simpleform/input/timerange",
  "splunkjs/mvc/simpleform/input/multiselect",
  "splunkjs/mvc/simpleform/input/dropdown",
  "splunkjs/mvc/simpleform/input/checkboxgroup",
  "splunkjs/mvc/simplexml/element/table",
  "splunkjs/mvc/simplexml/element/single",
  "splunkjs/mvc/simplexml/element/event",
  "splunkjs/mvc/simplexml/element/visualization",
  "splunkjs/mvc/simpleform/formutils",
  "splunkjs/mvc/simplexml/eventhandler",
  "splunkjs/mvc/simplexml/searcheventhandler",
  "splunkjs/mvc/simplexml/ready!",
], function (
  $,
  _,
  mvc,
  utils,
  SearchControlsView,
  SearchManager,
  PostProcessManager,
  DropdownView,
  MultiDropdownView,
  TableView,
  EventsViewer,
  TextInputView,
  SingleView,
  ChartView,
  ResultsLinkView,
  SearchEventHandler,
  VisualizationRegistry,
  LinkListInput,
  TextInput,
  TimeRangeInput,
  MultiSelectInput,
  DropdownInput,
  CheckboxGroupInput,
  TableElement,
  VisualizationElement,
  SingleElement,
  EventElement,
  FormUtils,
  EventHandler,
  SearchEventHandler
) {
  //
  // START
  //

  // tokens

  var defaultTokenModel = mvc.Components.getInstance("default", {
    create: true,
  });
  var submittedTokenModel = mvc.Components.getInstance("submitted", {
    create: true,
  });

  function setToken(name, value) {
    defaultTokenModel.set(name, value);
    submittedTokenModel.set(name, value);
  }

  function getToken(name) {
    var ret = null;
    if (defaultTokenModel.get(name) != undefined) {
      ret = defaultTokenModel.get(name);
    } else if (submittedTokenModel.get(name) != undefined) {
      ret = submittedTokenModel.get(name);
    }
    return ret;
  }

  function unsetToken(name) {
    defaultTokenModel.unset(name);
    submittedTokenModel.unset(name);
  }

  // close all opened modals
  function closeModals() {
    $(".modal").modal("hide");
  }

  // ajax promise for API calls
  async function asyncAjax(ajaxurl, ajaxType, ajaxdata) {
    var resultCall;
    try {
      resultCall = await $.ajax({
        url: ajaxurl,
        type: ajaxType,
        data: JSON.stringify(ajaxdata),
      });
      // return resultUiPrefs
      $("#modal_generic_success").modal();
      // we do not want to catch the error
    } catch (error) {
      closeModals();
      $("#modal_generic_error")
        .find(".modal-error-message p")
        .text(JSON.stringify(error));
      $("#modal_generic_error").modal();
    }
  }

  //
  // searches
  //

  var search1 = new SearchManager(
    {
      id: "search1",
      earliest_time: "0",
      status_buckets: 0,
      sample_ratio: 1,
      latest_time: "now",
      cancelOnUnload: true,
      search:
        "| inputlookup nmon_frameID_mapping | $user_selection$ | search frameID=* serialnum=* host=* host_description=* | eval  KeyID = _key | table KeyID,frameID,serialnum,host,host_description,*",
      app: utils.getCurrentApp(),
      auto_cancel: 90,
      preview: true,
      runWhenTimeIsUndefined: false,
    },
    { tokens: true, tokenNamespace: "submitted" }
  );

  var search2 = new SearchManager(
    {
      id: "search2",
      earliest_time: "-24h",
      sample_ratio: 1,
      status_buckets: 0,
      cancelOnUnload: true,
      latest_time: "now",
      search:
        "| inputlookup nmon_frameID_mapping | where frameID=host | stats dc(host) as count",
      app: utils.getCurrentApp(),
      auto_cancel: 90,
      preview: true,
      runWhenTimeIsUndefined: false,
    },
    { tokens: true, tokenNamespace: "submitted" }
  );

  var search3 = new SearchManager(
    {
      id: "search3",
      earliest_time: "0",
      status_buckets: 0,
      sample_ratio: 1,
      latest_time: "now",
      cancelOnUnload: true,
      search:
        '| inputlookup nmon_frameID_mapping | eval  KeyID = _key | table KeyID,frameID,serialnum,host,host_description,* | fillnull value="none" | search KeyID=$search_keyID$ frameID=$search_frameID$ serialnum=$search_serialnum$ host=$search_host$ host_description=$search_host_description$',
      app: utils.getCurrentApp(),
      auto_cancel: 90,
      preview: true,
      runWhenTimeIsUndefined: false,
    },
    { tokens: true, tokenNamespace: "submitted" }
  );

  var search4 = new SearchManager(
    {
      id: "search4",
      earliest_time: "-7d",
      status_buckets: 0,
      sample_ratio: 1,
      latest_time: "now",
      cancelOnUnload: true,
      search:
        "| inputlookup nmon_frameID_mapping | stats dc(host) as host_in_lookup | appendcols [ | tstats dc(host) as host_in_data WHERE `nmon_index` sourcetype=nmon_data ] | eval delta=if(host_in_lookup>host_in_data, host_in_lookup-host_in_data, host_in_data-host_in_lookup) | fields delta",
      app: utils.getCurrentApp(),
      auto_cancel: 90,
      preview: true,
      runWhenTimeIsUndefined: false,
    },
    { tokens: true, tokenNamespace: "submitted" }
  );

  var search5 = new SearchManager(
    {
      id: "search5",
      earliest_time: "-7d",
      status_buckets: 0,
      sample_ratio: 1,
      latest_time: "now",
      cancelOnUnload: true,
      search:
        "| inputlookup nmon_frameID_mapping | stats count by host | where count>1 | stats dc(host) as count",
      app: utils.getCurrentApp(),
      auto_cancel: 90,
      preview: true,
      runWhenTimeIsUndefined: false,
    },
    { tokens: true, tokenNamespace: "submitted" }
  );

  var search6 = new SearchManager(
    {
      id: "search6",
      earliest_time: "-7d",
      status_buckets: 0,
      sample_ratio: 1,
      latest_time: "now",
      cancelOnUnload: true,
      search:
        "| mcatalog values(serialnum) as serials where `nmon_metrics_index` metric_name=os.unix.nmon.* by host | rename serials as serialnum | lookup nmon_frameID_mapping host as host OUTPUT frameID | where isnull(frameID)",
      app: utils.getCurrentApp(),
      auto_cancel: 90,
      preview: true,
      runWhenTimeIsUndefined: false,
    },
    { tokens: true, tokenNamespace: "submitted" }
  );

  new SearchEventHandler({
    managerid: "search6",
    event: "progress",
    conditions: [
      {
        attr: "match",
        value: "'job.resultCount' == 0",
        actions: [{ type: "unset", token: "show_null_missing_frameID" }],
      },
      {
        attr: "any",
        value: "*",
        actions: [
          { type: "set", token: "show_null_missing_frameID", value: "True" },
        ],
      },
    ],
  });

  function updateAllSearches() {
    search1.startSearch();
    search2.startSearch();
    search3.startSearch();
    search4.startSearch();
    search5.startSearch();
    search6.startSearch();
  }

  // singles
  var element_unset_frameID = new SingleView(
    {
      id: "element_unset_frameID",
      unitPosition: "after",
      numberPrecision: "0",
      drilldown: "all",
      useColors: "1",
      trendDisplayMode: "absolute",
      rangeValues: "[0]",
      colorBy: "value",
      showTrendIndicator: "1",
      showSparkline: "1",
      colorMode: "none",
      trendColorInterpretation: "standard",
      underLabel: "Number of frameID undefined (frameID=hostname)",
      useThousandSeparators: "1",
      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
      managerid: "search2",
      el: $("#element_unset_frameID"),
    },
    { tokens: true, tokenNamespace: "submitted" }
  ).render();

  var element_delta_frameID = new SingleView(
    {
      id: "element_delta_frameID",
      unitPosition: "after",
      numberPrecision: "0",
      drilldown: "all",
      useColors: "1",
      trendDisplayMode: "absolute",
      rangeValues: "[0]",
      colorBy: "value",
      showTrendIndicator: "1",
      showSparkline: "1",
      colorMode: "none",
      trendColorInterpretation: "standard",
      underLabel:
        "Number of host(s) in delta (more hosts in data or more hosts in collection)",
      useThousandSeparators: "1",
      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
      managerid: "search4",
      el: $("#element_delta_frameID"),
    },
    { tokens: true, tokenNamespace: "submitted" }
  ).render();

  var element_duplicated_hosts = new SingleView(
    {
      id: "element_duplicated_hosts",
      unitPosition: "after",
      numberPrecision: "0",
      drilldown: "all",
      useColors: "1",
      trendDisplayMode: "absolute",
      rangeValues: "[0]",
      colorBy: "value",
      showTrendIndicator: "1",
      showSparkline: "1",
      colorMode: "none",
      trendColorInterpretation: "standard",
      underLabel: "Number of host(s) with duplicated entries in the collection",
      useThousandSeparators: "1",
      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
      managerid: "search5",
      el: $("#element_duplicated_hosts"),
    },
    { tokens: true, tokenNamespace: "submitted" }
  ).render();

  // tables

  var element_table_show_lookup_content = new TableView(
    {
      id: "element_table_show_lookup_content",
      count: 10,
      dataOverlayMode: "none",
      drilldown: "row",
      percentagesRow: "false",
      rowNumbers: "false",
      totalsRow: "false",
      wrap: "true",
      managerid: "search3",
      el: $("#element_table_show_lookup_content"),
    },
    { tokens: true, tokenNamespace: "submitted" }
  ).render();

  element_table_show_lookup_content.on("click", function (e) {
    if (e.field !== undefined) {
      e.preventDefault();
      // Populate input form for deletion and addition
      setToken("tk_keyid", e.data["row.KeyID"]);
      setToken("form.modify_frameid", e.data["row.frameID"]);
      setToken("form.modify_serialnum", e.data["row.serialnum"]);
      setToken("form.modify_host", e.data["row.host"]);
      setToken("form.modify_host_description", e.data["row.host_description"]);
      $("#modal_update_entity").modal();
    }
  });

  var element_table_missing_content = new TableView(
    {
      id: "element_table_missing_content",
      count: 10,
      dataOverlayMode: "none",
      drilldown: "row",
      percentagesRow: "false",
      rowNumbers: "false",
      totalsRow: "false",
      wrap: "true",
      managerid: "search6",
      el: $("#element_table_missing_content"),
    },
    { tokens: true, tokenNamespace: "submitted" }
  ).render();

  element_table_missing_content.on("click", function (e) {
    if (e.field !== undefined) {
      e.preventDefault();
      // Populate input form for deletion and addition
      setToken("form.add_frameID", e.data["row.frameID"]);
      setToken("form.add_serialnum", e.data["row.serialnum"]);
      setToken("form.add_host", e.data["row.host"]);
      setToken("form.add_host_description", e.data["row.host_description"]);
      $("#modal_add_entity").modal();
    }
  });

  // link input
  var inputLink = new LinkListInput(
    {
      id: "inputLink",
      choices: [
        {
          value: "frameid_collection",
          label: "FrameID current collection",
        },
        {
          value: "missing_hosts",
          label: "Hosts missing in the collection",
        },
      ],
      default: "frameid_collection",
      searchWhenChanged: true,
      selectFirstChoice: false,
      initialValue: "frameid_collection",
      value: "$form.inputLink$",
      el: $("#inputLink"),
    },
    {
      tokens: true,
    }
  ).render();

  inputLink.on("change", function (newValue) {
    setToken("inputLink", newValue);
  });

  inputLink.on("valueChange", function (e) {
    if (e.value === "frameid_collection") {
      // show and hide elements
      $("#tableParent1").css("display", "inherit");
      $("#tableParent2").css("display", "none");
    } else if (e.value === "missing_hosts") {
      // show and hide elements
      $("#tableParent1").css("display", "none");
      $("#tableParent2").css("display", "inherit");
    }
  });

  // inputs

  // inputs for searching purposes

  var input_search_keyid = new TextInput(
    {
      id: "input_search_keyid",
      value: "$form.search_keyID$",
      default: "*",
      searchWhenChanged: true,
      el: $("#input_search_keyid"),
    },
    { tokens: true }
  ).render();

  input_search_keyid.on("change", function (newValue) {
    setToken("search_keyID", newValue);
  });

  var input_search_frameid = new TextInput(
    {
      id: "input_search_frameid",
      value: "$form.search_frameID$",
      default: "*",
      searchWhenChanged: true,
      el: $("#input_search_frameid"),
    },
    { tokens: true }
  ).render();

  input_search_frameid.on("change", function (newValue) {
    setToken("search_frameID", newValue);
  });

  var input_search_serialnum = new TextInput(
    {
      id: "input_search_serialnum",
      value: "$form.search_serialnum$",
      default: "*",
      searchWhenChanged: true,
      el: $("#input_search_serialnum"),
    },
    { tokens: true }
  ).render();

  input_search_serialnum.on("change", function (newValue) {
    setToken("search_serialnum", newValue);
  });

  var input_search_host = new TextInput(
    {
      id: "input_search_host",
      value: "$form.search_host$",
      default: "*",
      searchWhenChanged: true,
      el: $("#input_search_host"),
    },
    { tokens: true }
  ).render();

  input_search_host.on("change", function (newValue) {
    setToken("search_host", newValue);
  });

  var input_search_host_description = new TextInput(
    {
      id: "input_search_host_description",
      value: "$form.search_host_description$",
      default: "*",
      searchWhenChanged: true,
      el: $("#input_search_host_description"),
    },
    { tokens: true }
  ).render();

  input_search_host_description.on("change", function (newValue) {
    setToken("search_host_description", newValue);
  });

  // inputs for modification purposes
  var input_modify_frameid = new TextInput(
    {
      id: "input_modify_frameid",
      value: "$form.modify_frameid$",
      el: $("#input_modify_frameid"),
    },
    { tokens: true }
  ).render();

  input_modify_frameid.on("change", function (newValue) {
    setToken("modify_frameid", newValue);
  });

  var input_modify_serialnum = new TextInput(
    {
      id: "input_modify_serialnum",
      value: "$form.modify_serialnum$",
      el: $("#input_modify_serialnum"),
    },
    { tokens: true }
  ).render();

  input_modify_serialnum.on("change", function (newValue) {
    setToken("modify_serialnum", newValue);
  });

  var input_modify_host = new TextInput(
    {
      id: "input_modify_host",
      value: "$form.modify_host$",
      el: $("#input_modify_host"),
    },
    { tokens: true }
  ).render();

  input_modify_host.on("change", function (newValue) {
    setToken("modify_host", newValue);
  });

  var input_modify_host_description = new TextInput(
    {
      id: "input_modify_host_description",
      value: "$form.modify_host_description$",
      el: $("#input_modify_host_description"),
    },
    { tokens: true }
  ).render();

  input_modify_host_description.on("change", function (newValue) {
    setToken("modify_host_description", newValue);
  });

  // inputs for addition purposes
  var input_add_frameid = new TextInput(
    {
      id: "input_add_frameid",
      value: "$form.add_frameID$",
      el: $("#input_add_frameid"),
    },
    { tokens: true }
  ).render();

  input_add_frameid.on("change", function (newValue) {
    setToken("add_frameID", newValue);
  });

  var input_add_serialnum = new TextInput(
    {
      id: "input_add_serialnum",
      value: "$form.add_serialnum$",
      el: $("#input_add_serialnum"),
    },
    { tokens: true }
  ).render();

  input_add_serialnum.on("change", function (newValue) {
    setToken("add_serialnum", newValue);
  });

  var input_add_host = new TextInput(
    {
      id: "input_add_host",
      value: "$form.add_host$",
      el: $("#input_add_host"),
    },
    { tokens: true }
  ).render();

  input_add_host.on("change", function (newValue) {
    setToken("add_host", newValue);
  });

  var input_add_host_description = new TextInput(
    {
      id: "input_add_host_description",
      value: "$form.add_host_description$",
      el: $("#input_add_host_description"),
    },
    { tokens: true }
  ).render();

  input_add_host_description.on("change", function (newValue) {
    setToken("add_host_description", newValue);
  });

  // interactions

  // help
  $("#btn_help")
    .unbind()
    .click(function () {
      $("#modal_help").modal();
    });

  // add new entry
  $("#btn_add_new_mapping")
    .unbind()
    .click(function () {
      $("#modal_add_entity").modal();
    });

  // submit new entry
  $("#btn_submit_new_entity").click(function () {
    var frameID = getToken("add_frameID");
    var serialnum = getToken("add_serialnum");
    var host = getToken("add_host");
    var host_description = getToken("add_host_description");

    // new record
    record = {
      frameID: getToken("add_frameID"),
      serialnum: getToken("add_serialnum"),
      host: getToken("add_host"),
      host_description: getToken("add_host_description"),
    };

    // Create the endpoint URL
    var myendpoint_URl =
      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_frameID_mapping/";

    // for sfatey check
    newHost = getToken("add_host");

    if (
      frameID &&
      frameID.length &&
      serialnum &&
      serialnum.length &&
      host &&
      host.length &&
      host_description &&
      host_description.length
    ) {
      $.ajax({
        url: myendpoint_URl,
        type: "POST",
        async: true,
        contentType: "application/json",
        data: JSON.stringify(record),
        success: function (returneddata) {
          // Return to modal
          $("#modal_generic_success").modal();
          // update searches
          updateAllSearches();
        },
        error: function (xhr, textStatus, error) {
          message = "Error Updating!" + xhr + textStatus + error;
          // Hide main modal
          closeModals();
          $("#modal_generic_error")
            .find(".modal-error-message p")
            .text(message);
          $("#modal_generic_error").modal();
        },
      });
    } else {
      message =
        "Error Updating! Please check your inputs: " + JSON.stringify(record);
      // Hide main modal
      closeModals();
      $("#modal_generic_error").find(".modal-error-message p").text(message);
      $("#modal_generic_error").modal();
    }
  });

  // delete entity
  $("#btn_submit_delete_entity").click(function () {
    // set keyid
    var tk_keyid = getToken("tk_keyid");
    // Create the endpoint URL
    var myendpoint_URl =
      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_frameID_mapping/" +
      tk_keyid;
    if (tk_keyid && tk_keyid.length) {
      $.ajax({
        url: myendpoint_URl,
        type: "DELETE",
        async: true,
        contentType: "application/json",
        success: function (returneddata) {
          // Return to modal
          $("#modal_generic_success").modal();
          // update searches
          updateAllSearches();
        },
        error: function (xhr, textStatus, error) {
          message = "Error Updating!" + xhr + textStatus + error;
          // Hide main modal
          closeModals();
          $("#modal_generic_error")
            .find(".modal-error-message p")
            .text(message);
          $("#modal_generic_error").modal();
        },
      });
    }
  });

  // update entity
  $("#btn_submit_update_entity").click(function () {
    // set vars
    var tk_keyid = getToken("tk_keyid");
    var frameID = getToken("modify_frameid");
    var serialnum = getToken("modify_serialnum");
    var host = getToken("modify_host");
    var host_description = getToken("modify_host_description");

    // update record
    record = {
      frameID: frameID,
      serialnum: serialnum,
      host: host,
      host_description: host_description,
    };
    // Create the endpoint URL
    var myendpoint_URl =
      "/en-US/splunkd/__raw/servicesNS/nobody/metricator-for-nmon/storage/collections/data/kv_nmon_frameID_mapping/" +
      tk_keyid;

    if (
      tk_keyid &&
      tk_keyid.length &&
      frameID &&
      frameID.length &&
      serialnum &&
      serialnum.length &&
      host &&
      host.length &&
      host_description &&
      host_description.length
    ) {
      $.ajax({
        url: myendpoint_URl,
        type: "POST",
        async: true,
        contentType: "application/json",
        data: JSON.stringify(record),
        success: function (returneddata) {
          // Return to modal
          $("#modal_generic_success").modal();
          // update searches
          updateAllSearches();
        },
        error: function (xhr, textStatus, error) {
          message = "Error Updating!" + xhr + textStatus + error;
          // Hide main modal
          closeModals();
          $("#modal_generic_error")
            .find(".modal-error-message p")
            .text(message);
          $("#modal_generic_error").modal();
        },
      });
    } else {
      message =
        "Error Updating! Please check your inputs: " + JSON.stringify(record);
      // Hide main modal
      closeModals();
      $("#modal_generic_error").find(".modal-error-message p").text(message);
      $("#modal_generic_error").modal();
    }
  });

  //
  // END
  //
});
