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");
  }

  // Returns true if numeric
  function isNumeric(n) {
    return !isNaN(parseFloat(n)) && isFinite(n) && n > 0;
  }

  // searches

  var search1 = new SearchManager(
    {
      id: "search1",
      earliest_time: "-5m",
      sample_ratio: 1,
      status_buckets: 0,
      cancelOnUnload: true,
      latest_time: "now",
      search:
        '| inputlookup nmon_alerting_filesystem_per_server_exclusion | where exclude="true" | stats count',
      app: utils.getCurrentApp(),
      auto_cancel: 90,
      preview: true,
      runWhenTimeIsUndefined: false,
    },
    { tokens: true, tokenNamespace: "submitted" }
  );

  var search2 = new SearchManager(
    {
      id: "search2",
      earliest_time: "-5m",
      status_buckets: 0,
      sample_ratio: 1,
      latest_time: "now",
      cancelOnUnload: true,
      search:
        "| inputlookup nmon_alerting_filesystem_per_server_exclusion | search frameID=$input_inventory_search_frameid$ serialnum=$input_inventory_search_serialnum$ host=$input_inventory_search_host$ mount=$input_inventory_search_mount$ | eval KeyID = _key | table KeyID,frameID,serialnum,host,mount,exclude",
      app: utils.getCurrentApp(),
      auto_cancel: 90,
      preview: true,
      runWhenTimeIsUndefined: false,
    },
    { tokens: true, tokenNamespace: "submitted" }
  );

  var search3 = new SearchManager(
    {
      id: "search3",
      earliest_time: "-5m",
      status_buckets: 0,
      sample_ratio: 1,
      latest_time: "now",
      cancelOnUnload: true,
      search:
        '| inputlookup nmon_alerting_filesystem_per_server_exclusion | where exclude="true" | stats dc(host) as dcount',
      app: utils.getCurrentApp(),
      auto_cancel: 90,
      preview: true,
      runWhenTimeIsUndefined: false,
    },
    { tokens: true, tokenNamespace: "submitted" }
  );

  var search4 = new SearchManager(
    {
      id: "search4",
      earliest_time: "-5m",
      status_buckets: 0,
      sample_ratio: 1,
      latest_time: "now",
      cancelOnUnload: true,
      search:
        '| inputlookup nmon_alerting_filesystem_per_server_exclusion | where exclude="true" | stats dc(mount) as dcount',
      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:
        "| mcatalog values(dimension_mount) as mount values(dimension_filesystem) as filesystem where `nmon_metrics_index` metric_name=os.unix.nmon.storage.df_storage* host=* groupby host, serialnum, OStype | `mapping_frameID` | fields frameID, host, serialnum, OStype, mount, filesystem | search frameID=$input_inventory_search_frameid$ serialnum=$input_inventory_search_serialnum$ host=$input_inventory_search_host$ mount=$input_inventory_search_mount$",
      app: utils.getCurrentApp(),
      auto_cancel: 90,
      preview: true,
      runWhenTimeIsUndefined: false,
    },
    { tokens: true, tokenNamespace: "submitted" }
  );

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

  // single views

  var element_unset_exclusions = new SingleView(
    {
      id: "element_unset_exclusions",
      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 file systems exclusion configured",
      useThousandSeparators: "1",
      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
      managerid: "search1",
      el: $("#element_unset_exclusions"),
    },
    { tokens: true, tokenNamespace: "submitted" }
  ).render();

  var element_nb_frameID = new SingleView(
    {
      id: "element_nb_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 distinct frameIDs excluded",
      useThousandSeparators: "1",
      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
      managerid: "search4",
      el: $("#element_nb_frameID"),
    },
    { tokens: true, tokenNamespace: "submitted" }
  ).render();

  var element_nb_mount = new SingleView(
    {
      id: "element_nb_mount",
      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 distinct mount points excluded",
      useThousandSeparators: "1",
      rangeColors: '["0x3F6FDE","0x3F6FDE"]',
      managerid: "search3",
      el: $("#element_nb_mount"),
    },
    { tokens: true, tokenNamespace: "submitted" }
  ).render();

  // link input
  var inputLink = new LinkListInput(
    {
      id: "inputLink",
      choices: [
        {
          value: "servers_inventory",
          label: "Servers inventory",
        },
        {
          value: "configured_exclusions",
          label: "Configured Exclusions",
        },
      ],
      default: "servers_inventory",
      searchWhenChanged: true,
      selectFirstChoice: false,
      initialValue: "servers_inventory",
      value: "$form.inputLink$",
      el: $("#inputLink"),
    },
    {
      tokens: true,
    }
  ).render();

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

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

  // tables

  var element_table_show_lookup_inventory = new TableElement(
    {
      id: "element_table_show_lookup_inventory",
      count: 10,
      dataOverlayMode: "none",
      drilldown: "row",
      format: { "storage used (%)": [{ options: {}, type: "color" }] },
      percentagesRow: "false",
      rowNumbers: "false",
      totalsRow: "false",
      wrap: "true",
      managerid: "search5",
      el: $("#element_table_show_lookup_inventory"),
    },
    { tokens: true, tokenNamespace: "submitted" }
  ).render();

  element_table_show_lookup_inventory.on("click", function (e) {
    if (e.field !== undefined) {
      e.preventDefault();
      // Populate input form for addition
      setToken("tk_keyid", e.data["row.KeyID"]);
      setToken("form.input_add_frameid", e.data["row.frameID"]);
      setToken("form.input_add_serialnum", e.data["row.serialnum"]);
      setToken("form.input_add_host", e.data["row.host"]);
      $("#modal_add_entity").modal();
    }
  });

  var element_table_show_lookup_content = new TableElement(
    {
      id: "element_table_show_lookup_content",
      count: 10,
      dataOverlayMode: "none",
      drilldown: "row",
      percentagesRow: "false",
      rowNumbers: "false",
      totalsRow: "false",
      wrap: "true",
      managerid: "search2",
      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();
      // set tk_keyid
      setToken("tk_keyid", e.data["row.KeyID"]);
      // Populate input forms
      setToken("form.input_update_frameid", e.data["row.frameID"]);
      setToken("form.input_update_serialnum", e.data["row.serialnum"]);
      setToken("form.input_update_host", e.data["row.host"]);
      setToken("form.input_update_mount", e.data["row.mount"]);
      // open modal
      $("#modal_update_entity").modal();
    }
  });

  // inventory searches

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

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

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

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

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

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

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

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

  // For additions

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

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

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

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

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

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

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

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

  // For update

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

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

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

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

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

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

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

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

  // interactions

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

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

  // submit new entry
  $("#btn_submit_new_entity").click(function () {
    console.log("clicked");
    var frameID = getToken("input_add_frameid");
    var host = getToken("input_add_host");
    var serialnum = getToken("input_add_serialnum");
    var mount = getToken("input_add_mount");

    // new record
    record = {
      frameID: frameID,
      host: host,
      serialnum: serialnum,
      mount: mount,
      exclude: "true",
    };

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

    if (
      frameID &&
      frameID.length &&
      host &&
      host.length &&
      serialnum &&
      serialnum.length &&
      mount &&
      mount.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 () {
    console.log("clicked");
    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_alerting_filesystem_per_server_exclusion/" +
      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 entry
  $("#btn_submit_update_entity").click(function () {
    console.log("clicked");
    var tk_keyid = getToken("tk_keyid");
    var frameID = getToken("input_update_frameid");
    var host = getToken("input_update_host");
    var serialnum = getToken("input_update_serialnum");
    var mount = getToken("input_update_mount");

    // new record
    record = {
      frameID: frameID,
      host: host,
      serialnum: serialnum,
      mount: mount,
      exclude: "true",
    };

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

    if (
      frameID &&
      frameID.length &&
      host &&
      host.length &&
      serialnum &&
      serialnum.length &&
      mount &&
      mount.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
  //
});
