/*
* Copyright (c) 2021 Xilinx, Inc.
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 
* associated documentation files (the "Software"), to deal in the Software without restriction, including 
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
* copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to 
* the following conditions: 
* 
* The above copyright notice and this permission notice shall be included in all copies or substantial 
* portions of the Software. 
* 
* 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.
* 
*
*
*/
import { PolymerElement, html } from "../node_modules/@polymer/polymer/polymer-element.js";
import { setPassiveTouchGestures, setRootPath } from "../node_modules/@polymer/polymer/lib/utils/settings.js";
import "../node_modules/@polymer/app-layout/app-drawer/app-drawer.js";
import "../node_modules/@polymer/app-layout/app-drawer-layout/app-drawer-layout.js";
import "../node_modules/@polymer/app-layout/app-header/app-header.js";
import "../node_modules/@polymer/app-layout/app-header-layout/app-header-layout.js";
import "../node_modules/@polymer/app-layout/app-scroll-effects/app-scroll-effects.js";
import "../node_modules/@polymer/app-route/app-location.js";
import "../node_modules/@polymer/app-route/app-route.js";
import "../node_modules/@polymer/iron-pages/iron-pages.js";
import "../node_modules/@polymer/iron-selector/iron-selector.js";
import "../node_modules/@polymer/iron-icons/iron-icons.js";
import "../node_modules/@polymer/iron-icons/editor-icons.js";
import "../node_modules/@polymer/iron-icons/av-icons.js";
import "../node_modules/@polymer/iron-icons/maps-icons.js";
import "../node_modules/@polymer/iron-icons/image-icons.js";
import "../node_modules/@polymer/iron-ajax/iron-ajax.js";
import "../node_modules/@polymer/paper-toast/paper-toast.js";
import "../node_modules/@polymer/paper-dialog/paper-dialog.js";
import "../node_modules/@polymer/neon-animation/animations/scale-up-animation.js";
import "../node_modules/@polymer/neon-animation/animations/fade-out-animation.js";
import "../node_modules/@polymer/paper-item/paper-item.js";
import "../node_modules/@polymer/paper-listbox/paper-listbox.js";
import "../node_modules/@polymer/paper-menu-button/paper-menu-button.js";
import "../node_modules/@polymer/paper-radio-button/paper-radio-button.js";
import "../node_modules/@polymer/paper-radio-group/paper-radio-group.js";
import './my-icons.js';
import "../node_modules/@vaadin/vaadin-menu-bar/vaadin-menu-bar.js";
setPassiveTouchGestures(true);
setRootPath(MyAppGlobals.rootPath);

class MyApp extends PolymerElement {
  static get template() {
    return html`
      <style>
        :host {
          --app-primary-color: #4285f4;
          --app-secondary-color: black;
          --app-drawer-scrim-background:rgba(0, 0, 0, 0.5);
          --app-drawer-width:250px;
          --custom-color:#262626;
          --lumo-primary-color-10pct: transparent;
          display: block;
        }
        app-drawer-layout:not([narrow]) [drawer-toggle] {
          display: none;
        }
        app-header-layout {
          z-index: 150;
        }
        app-header {
          color: #fff;
          background-color: #000000;
          padding: 10px 15px;
        }
        .drawer-list {
          overflow: hidden;
          display: block;
          margin: 20px 0;
          white-space: nowrap;
        }
        .drawer-list a {
          display: block;
          text-decoration: none;
          color: var(--app-secondary-color);
          font-size:18px;
          line-height: 30px;
        }
        a.iron-selected {
          color: black;
          font-weight: bold;
          background:#dedede;
        }
        #networkBtn,
        #disconnectBtn {
          pointer-events: auto;
          cursor:pointer;
        }
        input {
          pointer-events: auto;
          cursor:text;
        }
        .logo {
          margin:10px auto 0px;
          text-align: left;
          display: block;
          width: 100%;
        }
        .align-right {
          float:right;
        }
        input.form-input-style {
          border-radius:2px;
          padding:3px 6px;
          border:1px solid #c3c3c3;
          margin-left:12px;
        }
        .header-button {
          border:none;
          border-radius:2px;
          padding:4px 12px;
        }
        .info-text {
          font-size:14px;
        }
        .bgXilinx {
          background-color: #fff;
        }
        app-drawer-layout {
          padding-top: 59px;
        }
        app-drawer{
          background-color:#0079c1;
          --app-drawer-width: 256px;
          top: 59px;
          transition: all 0.5s ease-in-out;
        }
        #drawer.toggled {
          --app-drawer-width: 54px;
          width: 54px;
          transition: all 0.5s ease-in-out;
        }
        .toggledIron{
          margin-left: -202px;
        }
        #drawer a > span {
          transition: all 0.5s ease-in-out;
        }
        iron-icon {
          padding:8px 15px;
        }
        .active {
          transform: rotate(0deg);
          transition: all 0.2s ease-in-out;
        }
        .applayouttoggled .active {
          transform: rotate(180deg);
          transition: all 0.2s ease-in-out;
        }
        .anchorDisabled {
          opacity:0.6;
          pointer-events:none;
        }
        .lowopacity {
          opacity:0.4;
        }
        .iconproperties {
          color:#ee3626;
          height:18px;
        }
        iron-pages {
          height: 100%;
          overflow-y: auto;
          transition: all 0.2s ease-in-out;
        }
        #titlebar {
          display: inline-flex;
          align-items: center;
        }
        .alignMiddle {
          margin-right: 30px;
        }
        .alignMiddle img{
          vertical-align: middle;
        }
        paper-toast{
          --paper-toast-background-color:#f4a442;
          --paper-toast-color:#000000;
          font-size:14px;
          width: auto;
          height: auto;
          padding-right: 40px;
          left: auto !important;
          top: auto !important;
          right: 0;
        }
        .close-button{
          position: absolute;
          right: 10px;
          top: 10px;
          color:#000;
          padding:0px;
          cursor: pointer;
          min-width: 24px;
        }
        #configurationmodal, #versalmodal, #trddetailsmodal {
          min-width: 25vw;
          width: 35vw;
          border-radius:5px;
        }
        #configurationmodal h2 {
          background-color: #dedede;
        }
        .w-5 {
          width: 5em;
        }
        .text-right {
          text-align: right;
        }
        .userProfile {
          display: inline-block;
          float: right;
          margin-top: 1px;
        }
        .fit-top {
          max-width: fit-content !important;
        }
        .menuBody {
          outline: none;
        }
        #versalmodal .programversalcancelBtn, #versalmodal .programversalsaveBtn, #versalmodal .resetversalBtn {
          padding: 4px 8px;
          background-color: #1E88E5;
          color: #fff;
          font-size: 14px;
          font-weight: bold;
          text-align: center;
        }
        #versalmodal .dialogfooter {
          display: flex;
          justify-content: flex-end;
        }
        #radioBtnGrp {
          display: flex;
          flex-direction: column;
        }
        #radioBtnGrp iron-icon {
          height: 14px;
          padding: 0px;
        }
        #radioBtnGrp .radiotext {
          width: 335px;
          display: inline-block;
        }
        </style>
        <app-location route="{{route}}" url-space-regex="^[[rootPath]]"></app-location>
        <app-route route="{{route}}" pattern="[[rootPath]]:page" data="{{routeData}}" tail="{{subroute}}"></app-route>
        <app-header-layout has-scrolling-region="" id="appheaderlayout">
          <app-header slot="header" fixed condenses="" reveals="" effects="waterfall">
            <div main-title="" id="titlebar">
              <span class="active" style="margin-right: 15px;" hidden$="[[!storedUser.loggedin]]">
                <iron-icon icon="editor:format-indent-decrease" on-tap="_toggleMenu" slot="item-icon" style="color:#ee3626;cursor:pointer;padding:0px;"></iron-icon>
              </span>
              <span class="alignMiddle">
                <img src="../images/logoXilinx.png" alt="AMD" height="38" />
              </span>
              <span>ACAP Cockpit</span>
            </div>
            <div class="userProfile" title={{title}}>
              <vaadin-menu-bar class="menuBody" theme="tertiary-inline small" id="menudiv" on-item-selected="_callOnSelection">
              </vaadin-menu-bar>
            </div>
            <paper-dialog id="configurationmodal" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop>
              <div class="configurationcontent"></div>
            </paper-dialog>
            <paper-dialog id="trddetailsmodal" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop>
              <div class="header"><h2>TRD Details</h2></div>
              <div>TRD details will be shown up here</div>
            </paper-dialog>
            <paper-dialog id="versalmodal" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop>
              <div class="header"><h2>Program Versal</h2></div>
              <div class="dialogbody">
                <!-- <div class="trdDescription">TRD description will be updated here</div> -->
                <div class="trdRadioGrp">
                  <paper-radio-group selected={{selectedTRD}} id="radioBtnGrp">
                    <!-- <paper-radio-button name="trd1"><div class="radiotext">TRD1</div><iron-icon icon="help" title="help" on-click="_loadTRDdetails"></iron-icon></paper-radio-button>
                    <paper-radio-button name="trd2"><div class="radiotext">TRD2</div><iron-icon icon="help" title="help" on-click="_loadTRDdetails"></iron-icon></paper-radio-button>
                    <paper-radio-button name="trd3"><div class="radiotext">TRD3</div><iron-icon icon="help" title="help" on-click="_loadTRDdetails"></iron-icon></paper-radio-button>
                    <paper-radio-button name="manual">User Design</paper-radio-button> -->
                  </paper-radio-group>
                  <paper-input label="PDI Path" value={{pdipath}} always-float-label auto-validate hidden={{!isCustom}}>
                  </paper-input>
                </div>
              </div>
              <div class="dialogfooter">
                <paper-button class="programversalsaveBtn" on-tap="_callProgramVersal" raised noink>Program Versal</paper-button>
                <paper-button class="resetversalBtn" on-tap="_callResetVersal" raised noink>Reset Versal</paper-button>
                <paper-button class="programversalcancelBtn" dialog-dismiss raised noink>Close</paper-button>
              </div>
            </paper-dialog>
          </app-header>
          <paper-toast id="toast" duration="0" class="fit-top" text="">
            <paper-button on-click="_toggleToast" class="close-button"><iron-icon icon="close" style="padding:0px"></iron-icon></paper-button>
          </paper-toast>
        </app-header-layout>
        <app-drawer-layout id="appDrawer" fullbleed="" narrow="{{narrow}}">
          <!-- Drawer content -->
          <app-drawer id="drawer" slot="drawer" swipe-open="[[narrow]]" hidden$="[[!storedUser.loggedin]]">
            <iron-selector selected="[[page]]" attr-for-selected="name" class="drawer-list" role="navigation">
              <a name="xregv" href="[[rootPath]]xregv"><iron-icon icon="important-devices" slot="item-icon" class="iconproperties"></iron-icon><span>Register Reference</span></a>
              <a name="CLI" href="[[rootPath]]CLI" class="anchorDisabled"><iron-icon icon="picture-in-picture" slot="item-icon" class="iconproperties"></iron-icon><span>System Debugger</span></a>
              <a name="SM" href="[[rootPath]]SM" class="anchorDisabled"><iron-icon icon="timeline" slot="item-icon" class="iconproperties"></iron-icon><span>System Monitor</span></a>
              <a name="usertab" href="[[rootPath]]usertab" class="anchorDisabled"><iron-icon icon="chrome-reader-mode" slot="item-icon" class="iconproperties"></iron-icon><span>User Dashboard</span></a>
            </iron-selector>
          </app-drawer>
          <!-- Main content -->
          <iron-pages selected="[[page]]" attr-for-selected="name" role="main">
            <xregv-data name="xregv"></xregv-data>
            <system-debugger name="CLI"></system-debugger>
            <system-monitor name="SM"></system-monitor>
            <user-tab name="usertab"></user-tab>
            <login-view name="login"></login-view>
            <my-view404 name="view404"></my-view404>
          </iron-pages>
        </app-drawer-layout>
        <iron-ajax id="statusxhr" method="get" url=[[statusurl]] handle-as="json" content-type="application/json" last-response="{{lastResponse}}"></iron-ajax>
        <iron-ajax id="logoutxhr" method="get" url=[[logouturl]] handle-as="json" content-type="application/json" last-response="{{lastResponse}}"></iron-ajax>
        <iron-ajax id="disxhr" method="get" url=[[disconnecturl]] handle-as="json" content-type="application/json" last-response="{{lastResponse}}"></iron-ajax>
        <iron-ajax id="callxhr" method="post" url=[[connecturl]] body={"hostaddress":"{{hostaddress}}","port":{{port}}} handle-as="json" content-type="application/json" last-response="{{lastResponse}}"></iron-ajax>
        <iron-ajax id="configdatabase" method="get" url=[[versionurl]] handle-as="json" content-type="application/json" last-response="{{lastResponse}}" on-error="_handleErrorResponse"></iron-ajax>
        <iron-ajax id="userLogin" method="POST" content-type="application/json" handle-as="json" debounce-duration="300"></iron-ajax>
        <iron-ajax id="sendcommand" method="post" url="[[commandurl]]" body={{livecommand}} handle-as="json" content-type="application/json" last-response="{{lastResponse}}" on-error="_handleErrorResponse"></iron-ajax>
        <iron-ajax id="resetversal" method="get" url="[[reseturl]]" handle-as="json" content-type="application/json" last-response="{{lastResponse}}" on-error="_handleErrorResponse"></iron-ajax>
        `;
  }

  static get properties() {
    return {
      page: {
        type: String,
        reflectToAttribute: true,
        observer: '_pageChanged'
      },
      selectedTRD: {
        type: String,
        reflectToAttribute: true,
        observer: '_trdChanged'
      },
      commandurl: {
        type: String,
        value: MyAppGlobals.serverUrl + 'programversal/'
      },
      livecommand: {
        type: Object,
        value: {
          "board_type": "",
          "trd": "",
          "path": ""
        }
      },
      reseturl: {
        type: String,
        value: MyAppGlobals.serverUrl + 'resetversal/'
      },
      connecturl: {
        type: String,
        value: MyAppGlobals.serverUrl + 'connect/'
      },
      disconnecturl: {
        type: String,
        value: MyAppGlobals.serverUrl + 'disconnect'
      },
      statusurl: {
        type: String,
        value: MyAppGlobals.serverUrl + 'getconnectionstatus'
      },
      logouturl: {
        type: String,
        value: MyAppGlobals.serverUrl + 'logout/'
      },
      hostaddress: {
        type: String,
        value: ""
      },
      port: {
        type: String,
        value: ""
      },
      boardname: {
        type: String,
        value: ""
      },
      routeData: Object,
      subroute: Object,
      storedUser: {
        type: Object,
        value: {}
      },
      menulists: {
        type: Array,
        value: []
      },
      title: {
        type: String,
        value: "Board is not connected"
      },
      versionurl: {
        type: String,
        value: MyAppGlobals.serverUrl + 'getVersion'
      },
      isUseractive: {
        type: Boolean,
        value: false
      },
      isCustom: {
        type: Boolean,
        value: false
      }
    };
  }

  static get observers() {
    return ['_routePageChanged(routeData.page)'];
  }

  _routePageChanged(page) {
    this.storedUser = JSON.parse(localStorage.getItem('storedUser'));

    if (_.isEmpty(this.storedUser)) {
      this.$.drawer.setAttribute("class", "toggled");
      this.$.appheaderlayout.setAttribute("class", "applayouttoggled");
      this.$.appDrawer.querySelector('iron-pages').setAttribute("class", 'toggledIron');
      this.isUseractive = false;
    } else {
      this.isUseractive = true;

      if (!page) {
        this.page = 'xregv';
      } else if (['login', 'xregv', 'CLI', 'SM', 'usertab'].indexOf(page) !== -1) {
        this.page = page;
      } else {
        this.page = 'view404';
      }
    }

    if (!this.$.drawer.persistent) {
      this.$.drawer.close();
    }
  }

  _pageChanged(page) {
    switch (page) {
      case 'xregv':
        import('./xregv-data.js');
        break;

      case 'CLI':
        import('./system-debugger.js');
        break;

      case 'SM':
        import('./templates/systemmoniter/system-monitor.js');
        break;

      case 'usertab':
        import('./templates/userdashboard/user_tab.js');
        break;

      case 'login':
        import('./login-view.js');
        break;

      case 'view404':
        import('./my-view404.js');
        break;
    }
  }

  _toggleMenu(e) {
    this.$.drawer.toggleClass("toggled");
    this.$.appheaderlayout.toggleClass("applayouttoggled");
    this.$.appDrawer.querySelector('iron-pages').toggleClass('toggledIron');
  }

  _toggleToast() {
    this.$.toast.toggle();
  }

  _toggleConfiguration(val) {
    const ele = this.$.configurationmodal.querySelector(".configurationcontent");
    ele.innerHTML = '';
    ele.innerHTML = `<configuration-view data-key=${val}></configuration-view>`;
    this.$.configurationmodal.open();
  }

  _openprogramversalmodal() {
    let pdi_list = Object.keys(this.storedUser.pdi_list);
    let btngrp = "";

    _.each(pdi_list, (val, ind) => {
      btngrp += '<paper-radio-button name="' + val + '"><div class="radiotext">' + val + '</div></paper-radio-button>';
    });

    btngrp += '<paper-radio-button name="manual">User Design</paper-radio-button>';
    this.$.radioBtnGrp.innerHTML = btngrp;
    this.$.versalmodal.open();
  }

  _loadTRDdetails() {
    this.$.trddetailsmodal.open();
  }

  _callResetVersal() {
    document.querySelector("#pageloader").style.display = "block";
    let self = this;
    const session = JSON.parse(localStorage.getItem('storedUser'));
    self.$.resetversal.headers['uid'] = session.uid;
    let request = self.$.resetversal.generateRequest();
    request.completes.then(req => {
      let result = req.response;

      if (result.status === 'Fail') {
        self.notificationToast.setAttribute('text', 'Please Connect to board and try again');
        self.notificationToast.open();
        document.querySelector("#pageloader").style.display = "none";
        return;
      }

      self.notificationToast.setAttribute('text', 'Reset successfull');
      self.notificationToast.open();
      document.querySelector("#pageloader").style.display = "none";
    }, () => {
      if (request.status == 400) redirectToLogin();
    });
  }

  _callProgramVersal() {
    const board_type = this.storedUser.board_type.toLowerCase();
    let self = this;
    let devprogflag = true;
    this.livecommand.board_type = board_type;
    this.livecommand.trd = this.selectedTRD;

    if (this.selectedTRD === "manual") {
      this.livecommand.path = this.pdipath;

      if (this.pdipath === "") {
        devprogflag = false;
      }
    } else this.livecommand.path = "";

    if (this.selectedTRD !== undefined && devprogflag === true) {
      self.$.versalmodal.toggle();
      document.querySelector("#pageloader").style.display = "block";
      const session = JSON.parse(localStorage.getItem('storedUser'));
      self.$.sendcommand.headers['uid'] = session.uid;
      let request = self.$.sendcommand.generateRequest();
      request.completes.then(req => {
        document.querySelector("#pageloader").style.display = "none";
        let result = req.response;

        if (result.status === 'Fail') {
          self.notificationToast.setAttribute('text', 'Please reset versal and try again');
          self.notificationToast.open();
          return;
        }

        self.notificationToast.setAttribute('text', 'PDI programmed successfully');
        self.notificationToast.open();
      }, () => {
        if (request.status == 400) redirectToLogin();
      });
    } else {
      self.notificationToast.setAttribute('text', 'Please select design or provide design path to continue');
      self.notificationToast.open();
    }
  }

  _initiateSocketCommunication() {
    console.log("**************Socket initiated ***********************");
    let self = this;
    let tab_name = "active_connection";

    if ("WebSocket" in window) {
      const session = JSON.parse(localStorage.getItem('storedUser'));
      let ws = new WebSocket('ws://' + MyAppGlobals.socketUrl + '/ws?socketpath=browserhandler&uniquekey=' + session["uid"]);
      self.ws = ws;

      ws.onopen = () => {
        ws.send(JSON.stringify({
          "tab": tab_name,
          "uid": session["uid"]
        }));
      };

      ws.onmessage = evt => {
        console.log(" ********* data received from socket ***************");
        setTimeout(function () {
          ws.send(JSON.stringify({
            "tab": tab_name,
            "uid": session["uid"]
          }));
        }, 1000);
      };

      ws.onclose = () => {
        ws.send(JSON.stringify({
          "tab": "AB2CL",
          "uid": session["uid"]
        })); //self.logOut();                                                  
      };
    } else {
      notificationRef.setAttribute('text', "WebSocket NOT supported by your Browser!");
      notificationRef.open();
    }
  }

  callnetworkConnectBtn(hostAddr, portNum) {
    let domref = this;
    domref.hostaddress = domref.name ? domref.name : hostAddr;
    domref.port = domref.port ? domref.port : portNum;
    domref.portNum = domref.port;

    if (domref.hostaddress !== "" && domref.port !== "") {
      domref.$.configurationmodal.close();
      document.querySelector("#pageloader").style.display = "block";
      domref.$.callxhr.headers['uid'] = domref.storedUser.uid;
      let request = domref.$.callxhr.generateRequest();
      let menulist = domref.$.menudiv;
      request.completes.then(req => {
        if (req.response.status === "Success") {
          const psrefclk = parseFloat(req.response.psrefclk).toFixed(4);
          menulist.items = [{
            component: domref._createprofile(domref.storedUser.full_name),
            children: [{
              text: 'Board Details'
            }, {
              text: 'Program Versal'
            }]
          }];

          domref._connectedCheck('');

          domref.boardname = domref.hostaddress;
          domref.devicedna = req.response.devicedna;
          domref.refclk = psrefclk;
          domref.freadstatus = req.response.fread_status;
          MyAppGlobals.boardstatus = true;
          MyAppGlobals.boardname = domref.hostaddress;
          localStorage.setItem('devicedna', req.response.devicedna);
          localStorage.setItem('refclk', psrefclk);
          localStorage.setItem('freadstatus', req.response.fread_status);

          domref._addRemoveClass(false);

          if (req.response.boardpermission === 'S') domref.notificationToast.setAttribute('text', `Board REF_CLK is ${psrefclk} MHz. You don\'t have memory write permissions`);else domref.notificationToast.setAttribute('text', `Board REF_CLK is ${psrefclk} MHz`);
          domref.notificationToast.open();
        } else {
          domref.notificationToast.setAttribute('text', 'Connection failed. Please change the board details and try again');
          domref.notificationToast.open();
        }

        domref.port = "";
        domref.name = "";
        document.querySelector("#pageloader").style.display = "none";

        domref._generateTitle();
        domref._initiateSocketCommunication();
      }, () => {
        domref.port = "";
        domref.name = "";
        document.querySelector("#pageloader").style.display = "none";
        if (request.status == 400) domref.clearsession();
      });
    } else {
      domref.notificationToast.setAttribute('text', 'Please provide board details');
      domref.notificationToast.open();
    }
  }

  hideDisconnectBtn() {
    let domref = this;
    domref.name = '';
    domref.port = '';
    document.querySelector("#pageloader").style.display = "block";
    domref.$.disxhr.headers['uid'] = domref.storedUser.uid;
    let request = this.$.disxhr.generateRequest();
    request.completes.then(req => {
      if (req.response.status === "Success") {
        domref._addRemoveClass(true);

        window.history.pushState({}, null, '/xregv');
        window.dispatchEvent(new CustomEvent('location-changed'));
        window.location.reload();
        MyAppGlobals.boardstatus = false;
        localStorage.setItem('configperf', []);
      } else {
        this.notificationToast.setAttribute('text', 'Failed to disconnect the board. Please try again');
        this.notificationToast.open();
      }

      document.querySelector("#pageloader").style.display = "none";

      domref._generateTitle();
    }, () => {
      document.querySelector("#pageloader").style.display = "none";
      if (request.status == 400) domref.clearsession();
    });
  }

  _loginsuccess(e) {
    localStorage.setItem('storedUser', JSON.stringify(e.detail));
    this.storedUser = JSON.parse(localStorage.getItem('storedUser'));
    this.page = 'xregv';
    this.callnetworkConnectBtn("localhost", 54321);
  }

  logOut() {
    let domref = this;
    domref.$.disxhr.headers['uid'] = domref.storedUser.uid;
    document.querySelector("#pageloader").style.display = "block";
    let request = this.$.disxhr.generateRequest();
    request.completes.then(() => {
      domref._addRemoveClass(true);

      MyAppGlobals.boardstatus = false;
      domref.callLogout();
    }, () => {
      if (request.status == 400) domref.callLogout();
    });
  }

  callLogout() {
    let domref = this;
    domref.$.logoutxhr.headers['uid'] = domref.storedUser.uid;
    let logoutrequest = domref.$.logoutxhr.generateRequest();
    logoutrequest.completes.then(req => {
      domref.clearsession();
    }, () => {
      if (logoutrequest.status == 400) domref.clearsession();
    });
  }

  connectedCallback() {
    super.connectedCallback();
    this.$.drawer.shadowRoot.querySelector('#contentContainer').style.padding = 0;
    this.notificationToast = this.$.toast;
    let domref = this;

    if (!this.isUseractive) {
      this._login();
    }

    if (this.storedUser !== null && this.storedUser.loggedin) {
      MyAppGlobals.boardstatus = false;
      this.$.toast.fitInto = this.shadowRoot.querySelector('#titlebar');
      let $router = this.shadowRoot.querySelector("app-location");
      domref.name = $router.queryParams && $router.queryParams.hostname ? $router.queryParams.hostname : localStorage.getItem('hostname');
      domref.port = $router.queryParams && $router.queryParams.port ? $router.queryParams.port : localStorage.getItem("port");
      domref.$.statusxhr.headers['uid'] = domref.storedUser.uid;
      let menulist = domref.$.menudiv;
      let request = domref.$.statusxhr.generateRequest();
      request.completes.then(req => {
        if (req.response.status === "Success") {
          menulist.items = [{
            component: domref._createprofile(domref.storedUser.full_name),
            children: [{
              text: 'Board Details'
            }, {
              text: 'Program Versal'
            }]
          }];

          domref._connectedCheck('');

          MyAppGlobals.boardstatus = true;
          MyAppGlobals.boardname = req.response.hostname;
          domref.boardname = req.response.hostname;
          domref.devicedna = localStorage.getItem('devicedna');
          domref.refclk = localStorage.getItem('refclk');
          domref.freadstatus = localStorage.getItem('freadstatus');
          domref.portNum = req.response.port;

          if (domref.name && domref.port) {
            const statusBoard = domref.name == req.response.hostname && domref.port == req.response.port;

            if (!statusBoard) {
              domref.notificationToast.setAttribute('text', 'Already connected with different board details');
              domref.notificationToast.open();
            }
          }

          if (Object.keys($router.queryParams).length > 0) {
            window.history.pushState({}, null, '/xregv');
            window.dispatchEvent(new CustomEvent('location-changed'));
          }

          domref._addRemoveClass(false);
        } else {
          window.history.pushState({}, null, '/xregv');
          window.dispatchEvent(new CustomEvent('location-changed'));
          MyAppGlobals.boardstatus = false;
          menulist.items = [{
            component: domref._createprofile(domref.storedUser.full_name),
            children: [{
              text: 'Connect'
            }]
          }];

          domref._connectedCheck('color:#fff;');
        }

        domref._generateTitle();

        domref._initiateSocketCommunication();
      }, () => {
        if (request.status == 400) domref.clearsession();
      });
    }
  }

  _addRemoveClass(val) {
    const navref = this.$.drawer.querySelectorAll('iron-selector a');

    for (let i = 0; i < navref.length; i++) {
      if (i >= 1) val ? navref[i].classList.add('anchorDisabled') : navref[i].classList.remove('anchorDisabled');
    }
  }

  _createprofile(fullName) {
    const initialLetter = fullName.split(' ').map(x => x.charAt(0)).join('').substr(0, 2).toUpperCase();
    const item = window.document.createElement('vaadin-context-menu-item');
    const span = window.document.createElement('span');
    const styles = "padding: 8px; border: 1px solid #FFF; border-radius: 50%; margin-right: 5px; font-size: 12px;";
    span.setAttribute("style", styles);
    span.appendChild(window.document.createTextNode(initialLetter));
    item.appendChild(span);
    const name = window.document.createElement('span');
    name.appendChild(window.document.createTextNode(fullName));
    item.appendChild(name);
    const icon = window.document.createElement('iron-icon');
    icon.setAttribute('icon', 'arrow-drop-down');
    item.appendChild(icon);
    return item;
  }

  _callOnSelection(e) {
    const val = e.detail.value.text.trim();

    if (val == "Logout") {
      this.logOut();
    } else if (val == "Disconnect") {
      this.hideDisconnectBtn();
    } else if (val == "Program Versal") {
      this._openprogramversalmodal();
    } else {
      this._toggleConfiguration(val);
    }
  }

  clearsession() {
    localStorage.clear();
    window.history.pushState({}, null, '/login');
    window.dispatchEvent(new CustomEvent('location-changed'));
    window.location.reload();
    document.querySelector("#pageloader").style.display = "none";
  }

  _connectedCheck(color) {
    let menulist = this.$.menudiv.shadowRoot;
    const ele = menulist.querySelector('vaadin-menu-bar-button');
    ele.style = color;

    ele.onmouseover = () => {
      ele.style.opacity = 1;
    };
  }

  _generateTitle() {
    this.title = "Board is not connected";
    if (MyAppGlobals.boardstatus) this.title = `${this.boardname} board is connected`;
  }

  ready() {
    super.ready();
    import("./configure-view.js");
    MyAppGlobals['appRef'] = this;
  }

  _trdChanged(selectedTRD) {
    if (selectedTRD === "manual") this.isCustom = true;else this.isCustom = false;
  }

  _login() {
    const userName = "Username";
    const pass = "Password";

    const _self = this;

    if (userName && pass) {
      this.formData = {
        username: userName,
        password: pass,
        is_connected: navigator.onLine
      };
      this.$.userLogin.body = JSON.stringify(this.formData);
      this.$.userLogin.url = MyAppGlobals.serverUrl + "login/";
      let request = this.$.userLogin.generateRequest();
      request.completes.then(req => {
        let sUser = req.response;
        _self.$.configdatabase.headers['uid'] = request.xhr.getResponseHeader('uid');

        let versionrequest = _self.$.configdatabase.generateRequest();

        versionrequest.completes.then(req => {
          let dblist = req.response;
          sUser.versionarray = dblist;
          sUser.version = dblist[0];

          if (!sUser.hasOwnProperty('error')) {
            this.invalidCred = true;
            const url_string = window.location.href;
            const url = new URL(url_string);
            const name = url.searchParams.get("hostname");
            const port = url.searchParams.get("port");

            if (name && port) {
              localStorage.setItem('hostname', name);
              localStorage.setItem('port', port);
            }

            sUser.loggedin = true;
            sUser.uid = request.xhr.getResponseHeader('uid');

            this._loginsuccess({
              bubbles: true,
              composed: true,
              detail: sUser
            });
          } else {
            _self.invalidCred = false;
            alert(sUser.error);
          }
        }, () => {
          if (request.status == 400) redirectToLogin();
        });
      }, () => {
        if (request.response && request.response.error) {
          alert(request.response.error);
        }
      });
    }
  }

}

window.customElements.define('my-app', MyApp);
