<template>
  <div>
    <div class="row">
      <div class="col-12 d-flex justify-content-center text-center">
        <h4 class="text-info">Search</h4>
      </div>
    </div>

    <div class="row">
      <div class="col-6">
        <div class="input-group input-group-sm sm-6">
          <!-- --------------------------------------------------------- -->
          <!-- -------- date  satrt----------------------------------- -->
          <!-- --------------------------------------------------------- -->
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend">
              <button class="btn btn-outline-secondary" type="button">
                Start date
              </button>
            </div>
            <date-picker
              type="date"
              autocomplete="off"
              v-model="search.datestart"
              format="YYYY-MM-DD"
              lang="en"
            >
            </date-picker>
          </div>
        </div>
      </div>
      <!-- col -->

      <div class="col-6">
        <div class="input-group input-group-sm sm-6">
          <!-- --------------------------------------------------------- -->
          <!-- -------- date ----------------------------------- -->
          <!-- --------------------------------------------------------- -->
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend">
              <button class="btn btn-outline-secondary" type="button">
                End date
              </button>
            </div>
            <date-picker
              type="date"
              autocomplete="off"
              v-model="search.dateend"
              format="YYYY-MM-DD"
              lang="en"
            >
            </date-picker>

            <div class="input-group-append">
              <button
                class="btn btn-outline-primary"
                round
                type="button"
                @click="setFilter"
              >
                Go
              </button>
            </div>
          </div>
        </div>
      </div>
      <!-- col -->
    </div>
    <!-- row -->

    <div class="row">
      <div class="col-6">
        <div class="input-group input-group-sm sm-6">
          <div class="input-group-prepend">
            <div
              class="form-control custom-control custom-switch custom-control-inline"
            >
              <input
                type="checkbox"
                class="custom-control-input"
                id="log_logerror"
                v-model="logcheck.error"
              />
              <label class="custom-control-label" for="log_logerror"
                >Error</label
              >
            </div>

            <div
              class="form-control custom-control custom-switch custom-control-inline"
            >
              <input
                type="checkbox"
                class="custom-control-input"
                id="log_output"
                v-model="logcheck.output"
                data-size="large"
                data-toggle="toggle"
              />
              <label class="custom-control-label" for="log_output"
                >Output</label
              >
            </div>

            <div
              class="form-control custom-control custom-switch custom-control-inline"
            >
              <input
                type="checkbox"
                class="custom-control-input"
                id="log_log"
                v-model="logcheck.log"
              />
              <label class="custom-control-label" for="log_log">Log</label>
            </div>
          </div>
        </div>
      </div>
      <!-- col -->

      <div class="col-5">
        <div class="input-group input-group-sm sm-5 justify-content-end ">
          <div class="input-group-prepend">
            <div class="input-group-append">
              <button
                class="btn btn-outline-warning"
                round
                type="button"
                @click="Clearlog"
              >
                Clear
              </button>
            </div>

            <div class="input-group-append">
              <button
                class="btn btn-outline-primary"
                round
                type="button"
                @click="Hotlog"
              >
                Hot_log
              </button>
            </div>
          </div>
        </div>
      </div>
      <!-- col -->

      <div class="col-1"></div>
      <!-- col -->
    </div>
    <!-- row -->

    <div class="row rowlog overflow-auto">
      <div class="col-12" v-for="item in log_path">
        <b-row class="border-bottom" v-if="logview(item) === true">
          <b-col cols="2">
            <span
              class="badge badge-danger badge-pill"
              style="cursor: pointer"
              @click="clearLog()"
              >Clear</span
            >
          </b-col>

          <b-col cols="8" style="cursor: pointer" @click="selectPath(item)">
            {{ item }}
          </b-col>

          <b-col cols="2">
            <span
              class="badge badge-secondary badge-pill"
              v-if="log_path_lenght[item] == log_path_lenghtstatus[item]"
              >{{ log_path_lenght[item] }}</span
            >

            <span class="badge badge-primary badge-pill" v-else>{{
              log_path_lenght[item]
            }}</span>
          </b-col>
        </b-row>
      </div>
      <!-- col -->
      <div v-if="onEvent" class="table">
        <vuetable
          ref="vuetable"
          :api-mode="false"
          :data="localData"
          :fields="['message', 'timestamp', 'type', 'process_id', 'app_name']"
        >
        </vuetable>
      </div>
    </div>
    <!-- row -->
  </div>
</template>
<script>
import { mapState, mapGetters, mapActions, dispatch } from "vuex";
import Vue from "vue";
import store from "@/store/index";
import JSZip from "jszip";
import DatePicker from "vue2-datepicker";
import "vue2-datepicker/index.css";
import { DateTime } from "luxon";
import FileSaver from "file-saver";
import Vuetable from "vuetable-2";
import axios from "axios";

export default {
  components: {
    Vuetable,
    DatePicker,
  },
  data() {
    return {
      log_path: [],
      log_path_lenght: [],
      log_path_lenghtstatus: [],
      loglenghttotal: 32,
      onEvent: false,
      allHistory: false,
      search: {
        datestart: "",
        dateend: "",
        log: "",
        output: "",
        error: "",
      },
      logcheck: {
        log: true,
        error: true,
        output: true,
      },
      selected: [],
      showlloedit: true,
      issocket: "close",
      socketdata: "",
      logintoken: "",
      code: [],
      logdata: [],
      localData: [],
    };
  },
  methods: {
    async getuser(token) {
      var data = await this.checktoken(token);
      console.log("User: " + data.user + "  Token: " + data.token);
      this.$socket.client.emit("onevent", data.user);
    },
    async checktoken(value) {
      try {
        var token = value;
        var pipelines = {
          source: "ssologin",
        };
        var params = {
          pipeline: pipelines,
        };

        var options = {
          headers: {
            "content-type": "application/x-www-form-urlencoded",
            Authorization: `Bearer ${token}`,
          },
        };
        var res = await axios.post(
          "https://api.swarmlab.io/istokenvalidsso",
          params,
          options
        );
        return res.data;
      } catch (e) {
        if (
          e.message == "Request failed with status code 401" ||
          /401/i.test(e.message)
        ) {
          window.location.href = "https://api-login.swarmlab.io:8089";
        }
        console.error(e);
      }
    },
    Hotlog() {
      var logintoken = store.getters["pipelineLLO/gettoken"];
      //call to start on event logs
      this.onEvent = true;
    },
    Clearlog() {
      this.onEvent = false;
    },
    logview(item) {
      //console.log('path ' + JSON.stringify(item))
      if (this.logcheck.log) {
        if (item.endsWith("-log")) {
          return true;
        }
      }
      if (this.logcheck.error) {
        if (item.endsWith("-error")) {
          return true;
        }
      }
      if (this.logcheck.output) {
        if (item.endsWith("-output")) {
          return true;
        }
      }
    },
    async selectPath(path) {
      console.log("path " + JSON.stringify(path));
      var statuslenght = this.log_path_lenght[path];
      Vue.set(this.log_path_lenghtstatus, path, statuslenght);
      // -------------------------------------
      // send to AdhocView to view in code
      // -------------------------------------
      this.$root.$emit("playground_log_in", path);
    },
    async clearLog(path) {
      console.log("path " + JSON.stringify(path));
      Vue.set(this.log_path_lenght, path, 0);
      Vue.set(this.log_path_lenghtstatus, path, 0);
      var log = store.dispatch("pipelineLLO/rmlog", {
        path: path,
      });
    },
    async setFilter() {
      console.log(JSON.stringify(this.search));

      var ddd8 = JSON.stringify(this.search.datestart);
      ddd8 = ddd8.replace(/"/g, ""); //"
      var datestart = DateTime.fromISO(ddd8, { zone: "Europe/Athens" });
      //console.log(datestart.zoneName); //=> 'Europe/Paris'
      //console.log(datestart.toString()); //=> 'Europe/Paris'

      var ddd18 = JSON.stringify(this.search.dateend);
      ddd18 = ddd18.replace(/"/g, ""); //"
      var dateend = DateTime.fromISO(ddd18, { zone: "Europe/Athens" });

      var restapi = "on";
      var logrestapi = await store.dispatch("pipelineLLO/setRestapi", {
        restapi: restapi,
      });
      var swarmlabname = new URL(location.href).searchParams.get(
        "pipelinename"
      );
      var log = await store.dispatch("pipelineLLO/get_log", {
        datestart: datestart.toISODate(),
        dateend: dateend.toISODate(),
        swarmlabname: swarmlabname,
      });
      var mongolog = store.getters["pipelineLLO/getmongolog"];
      console.log("paramp " + JSON.stringify(mongolog));

      //this.$root.$emit('GREP_on_data',mongolog.data.data)

      // list files from data
      this.log_path = [...new Set(mongolog.map((item) => item.tailed_path))];
      var loglenght = "";
      for (let item of this.log_path) {
        loglenght = mongolog.filter((item1) => item1.tailed_path === item)
          .length;
        Vue.set(this.log_path_lenght, item, loglenght);
        if (loglenght > this.loglenghttotal) {
          // -------------------------------------
          //  Save store
          // -------------------------------------
          var ltotal1 = store.dispatch("pipelineLLO/taillog", {
            path: item,
          });
        }
      }
    },
    async resetFilter() {
      console.log(JSON.stringify(this.logdata));
    },
    async socketopen() {
      this.$socket.client.open();
    },
    async socketauthenticate() {
      var tokentmp = store.getters["pipelineLLO/gettoken"];
      // pernaw hardcoded to token
      this.$socket.client.emit("authenticate", tokentmp);
    },
    async socketreconnect() {
      var log = await this.socketopen();
      this.socketauthenticate();
    },
    /**
     *
     * == socketclose()
     *
     * [source,javascript]
     * ----
     *       this.$socket.client.close();
     * ----
     *
     */

    async socketclose() {
      this.$socket.client.close();
    },
  },
  computed: {
    httpOptions() {
      var token = store.getters["pipelineLLO/gettoken"];
      return {
        headers: {
          "Access-Control-Allow-Origin": "*",
        },
      }; //table props -> :http-options="httpOptions"
    },
  },
  beforeMount() {
    this.socketauthenticate();
    console.log("send1");
  },

  /**
 *
 * == Socket subscribe
     *
 * [source,javascript]
 * ----
 *          ...
 *          })
     * sdfsf
     den to perni  sdfsf
 * ----
 * <1> EventBus is used for parent/child component communication.
 *
 */
  mounted() {
    // from AdhocView
    this.$root.$on("SERVER_socket_connect", (v) => {
      this.$nextTick(function() {
        this.socketreconnect();
      });
    });
  },
  /**
   *
   * == Destroy EventBus
   *
   * See
   * https://www.digitalocean.com/community/tutorials/vuejs-component-lifecycle[Vue.js Lifecycle Hooks^].
   *
   * *beforeDestroy*
   *
   * - beforeDestroy is fired right before teardown. Your component will still be fully present and functional.
   *
   * [source,javascript]
   * ----
   * ----
   * <1> EventBus is used for parent/child component communication.
   *
   */
  beforeDestroy() {
    this.$root.$off("SERVER_socket_socket");
  },
  /**
   *
   * == Open a socket
   *
   * See
   * https://www.digitalocean.com/community/tutorials/vuejs-component-lifecycle[  Vue.js Lifecycle Hooks^]
   *
   * *Created*
   *
   * - You are able to access reactive data and events that are active with the created hook. Templates and Virtual DOM have not yet been mounted or rendered:
   *
   * [source,javascript]
   * ----
   *   this.socketopen()
   * ----
   *
   */

  created() {
    //var logintoken = new URL(location.href).searchParams.get("token");
    var logintoken = new URL(
      "https://api-client.swarmlab.io:8088/?token=1a4a350776b73bcb2e80194716bc90d4e78ae9dc"
    ).searchParams.get("token");
    this.logintoken = logintoken;
    // === We get the user + check for the token if exists
    this.checktoken(this.logintoken);
    //console.log(" from created ", data);
    var log = store.dispatch("pipelineLLO/settoken", {
      token: logintoken,
    });

    this.socketopen();

    // let p = axios.get("http://localhost:3000/test");
    // console.log(p);
  },
  /**
   *
   * == Socket events
   *
   * [source,javascript]
   * ----
   *   this.$socket.client.emit('authenticate', 'logintoken');
   * ----
   *
   */
  sockets: {
    connect() {
      var logintoken = store.getters["pipelineLLO/gettoken"];
      this.$socket.client.emit("authenticate", logintoken);

      this.$socket.client.emit("socket_id_get", "socketdatasend");
      //var username = 'username'
      //var roomname = 'roomname'
      //this.$socket.client.emit('setUsername',{user:username});
      //this.$socket.client.emit('createRoom', {user:username,room:roomname});
      //this.$socket.client.emit('joinRooom',{room:roomname});
      //var msg = {user:username,room:roomname,msg:'hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii'}
      //this.$socket.client.emit('sendMessage',msg);
      console.log("socket connected " + "socketdatasend");
      this.issocket = "open";
      // send to AdhocView
      this.$root.$emit("SERVER_socket_status", "on");
      this.getuser(logintoken);
    },
    /**
     *
     * === onError
     *
     */
    error(error) {
      console.log("socket error " + JSON.stringify(error));
      this.issocket = "close";
      // send to AdhocView
      this.$root.$emit("SERVER_socket_status", "off");
    },
    /**
     *
     * === connect_error
     *
     */
    connect_error(error) {
      console.log("socket connect_error " + JSON.stringify(error));
      this.issocket = "close";
      // send to AdhocView
      this.$root.$emit("SERVER_socket_status", "off");
      this.socketreconnect();
    },
    /**
     *
     * === connect_error
     *
     */
    disconnect(reason) {
      console.log("socket disconnect " + JSON.stringify(reason));
      this.issocket = "close";
      // send to AdhocView
      this.$root.$emit("SERVER_socket_status", "off");
      this.socketreconnect();
    },
    /**
     *
     * === Socket connect_timeout
     *
     */
    connect_timeout(reason) {
      console.log("socket timeout " + JSON.stringify(reason));
      this.issocket = "close";
      // send to AdhocView
      this.$root.$emit("SERVER_socket_status", "off");
      this.socketreconnect();
    },
    /**
     *
     * === Socket reconnect
     *
     */
    reconnect(attemptNumber) {
      console.log(
        "socket reconnect attemptNumber " + JSON.stringify(attemptNumber)
      );
      // send to AdhocView
      this.$root.$emit("SERVER_socket_status", "off");
      this.socketreconnect();
    },
    /**
     *
     * === connect_attempt
     *
     */
    reconnect_attempt(attemptNumber) {
      console.log("socket reconnect_attempt " + JSON.stringify(attemptNumber));
      // send to AdhocView
      this.$root.$emit("SERVER_socket_status", "off");
      this.socketreconnect();
    },
    /**
     *
     * === Socket reconnecting
     *
     */
    reconnecting(attemptNumber) {
      console.log("socket reconnecting " + JSON.stringify(attemptNumber));
      this.$root.$emit("SERVER_socket_status", "off");
      this.socketreconnect();
    },
    /**
     *
     * === reconnect_error
     *
     */
    reconnect_error(error) {
      console.log("socket reconnect_error " + JSON.stringify(error));
      this.issocket = "close";
      // send to AdhocView
      this.$root.$emit("SERVER_socket_status", "off");
      this.socketreconnect();
    },
    /**
     *
     * === unauthorized
     *
     */
    unauthorized(val) {
      console.log("socket unauthorized " + JSON.stringify(val));
      this.issocket = "close";
      // send to AdhocView
      this.$root.$emit("SERVER_socket_status", "off");
    },
    /**
     *
     * === connected
     *
     */
    socket_id_emit(val) {
      console.log("socket id from server " + JSON.stringify(val));
      console.log("socket id from serveri saved " + JSON.stringify(socketsave));
      this.issocket = "open";
    },
    /**
     *
     * === Socket onMessage
     *
     */
    /*
      async adhocEmit(val) {
        console.log("socket from server "+JSON.stringify(val))
        this.issocket = 'open'
            this.$wait.start('myRunInstance1');
                // render begin
                this.tryLLO = 'on'
                if(this.firstbootstrap === 0 ){
                    await this.bootsrapllo();
                    this.firstbootstrap = 1
                }
                var output = log.data.out
                var mydinfunction = `
                  <div class="row">
                      <b-col  class="" cols="12" sm="12"  md="12" >
                            ${output}
                       </b-col>
                  </div>`

                  try {
                     let divascii = document.createElement('div');
                     divascii.setAttribute("class", "container-fluid w-100 p-3 llotry")
                     divascii.innerHTML = mydinfunction
                     this.addtask(divascii);
                  }catch (ex) {
                      console.log(" logi error1 "+JSON.stringify(ex))
                      return
                  }
            this.$wait.end('myRunInstance1');
      },
      */
    async logdata(val) {
      console.log(" socket from logdata " + JSON.stringify(val));
      // -------------------------------------
      //  Save store
      // -------------------------------------
      var log = store.dispatch("pipelineLLO/addlog", {
        log: val,
      });
      // -------------------------------------
      // send to grep rungrep to view
      // -------------------------------------
      this.$root.$emit("GREP_on_data", val);
      // -------------------------------------
      // send to AdhocView to view in code
      // -------------------------------------
      //  this.$root.$emit('playground_log_in',val.value)
      // -------------------------------------
      // send to AdhocView for socket status
      // -------------------------------------
      this.$root.$emit("SERVER_socket_status", "on");

      var ltmp = store.getters["pipelineLLO/getlog"];
      //console.log('logtmpltmp '+ JSON.stringify(ltmp))
      this.log_path = [...new Set(ltmp.map((item) => item.tailed_path))];
      var loglenght = "";
      for (let item of this.log_path) {
        //console.log('l1find '+ JSON.stringify(item))
        loglenght = ltmp.filter((item1) => item1.tailed_path === item).length;
        Vue.set(this.log_path_lenght, item, loglenght);
        if (loglenght > this.loglenghttotal) {
          // -------------------------------------
          //  Save store
          // -------------------------------------
          var ltotal1 = store.dispatch("pipelineLLO/taillog", {
            path: item,
          });
        }
        /*
             this.log_path_lenght[item] = ltmp.filter(function(item1){
                if (item1.tailed_path === item) {
                  return true;
                } else {
                  return false;
                }
              }).length;/
              */
        //console.log('l2 '+ this.log_path_lenght[item] )
      }
      //console.log('l1 '+ JSON.stringify(this.log_path))
    },
    async message(val) {
      console.log(" socket message " + JSON.stringify(val));
    },
    async logsend(val) {
      // ==== LEFOS
      console.log(" socket message " + JSON.stringify(val));

      // var log = val.log;
      // console.log(" LOG:  " + JSON.parse(JSON.stringify(log)));

      var log = store.dispatch("pipelineLLO/addlog", {
        log: val,
      });

      this.localData.push(val);
    },
  },
};
</script>

<style>
.table {
  overflow: scroll;
  min-width: 700px;
  max-width: 1200px;
  max-height: 550px;
}
.CodeMirror {
  font-family: monospace;
  height: 750px;
}
.rowlog {
  display: flex; /* equal height of the children */
  height: 470px;
}
</style>
