<template lang="html">
  <div id="workspace">
    <div class="modal" id="submission-modal">
      <div class="modal-content">
        <div class="container form-container">
          <h4>Execute Workflows</h4>
          <div class="row">
            <div class="input-field col s12">
              <select class="browser-default" id="config-select" v-model="submission_config" v-on:input="preflight(self_ref)">
                <option value="" selected disabled>Choose a method</option>
                <option v-for="config in method_configs" v-bind:value="config.name" :key="config.name">
                  {{config.name}}
                </option>
              </select>
            </div>
          </div>
          <div class="row">
            <div class="input-field col s6 inline">
              <select class="browser-default" id="etype-select" v-model="submission_etype" v-on:input="preflight(self_ref)">
                <option value="" selected disabled>Choose an entity type</option>
                <option v-for="etype in entity_types" v-bind:value="etype.type" >
                  {{etype.type}}
                </option>
              </select>
            </div>
            <div class="input-field col s6">
              <input type="text" id="entity-input" required v-model="entity_field" v-on:input="preflight(self_ref)"/>
              <label style="z-index: -1;">Workflow Entity</label>
            </div>
          </div>
          <div class="row">
            <div class="input-field col s12">
              <input type="text" id="expression-input" v-model="submission_expression" v-bind:disabled="extract_etype(submission_config) == submission_etype" v-on:input="preflight(self_ref)"/>
              <label style="z-index: -1;">Entity Expression (optional)</label>
            </div>
          </div>
          <div v-if="submission_message != ''" class="row">
            <div class="col s12" v-if="submission_message == '-'">
              Validating inputs...
            </div>
            <div v-else class="col s12" v-bind:class="submit_okay ? 'green-text' : 'red-text'">
              {{(submit_okay ? "" : "Error: ") + submission_message}}
            </div>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <a class="btn-flat" v-bind:class="submit_okay ? '' : 'disabled'" v-on:click="submit_workflow">Run</a>
      </div>
    </div>
    <h4>{{namespace}}/{{workspace}}</h4>
    <div class="divider">

    </div>
    <div class="row">
      <div class="col s6">
        <h5><a rel="noopener" target="_blank" v-bind:href="'https://portal.firecloud.org/#workspaces/'+namespace+'/'+workspace">Visit Workspace in Firecloud</a></h5>
      </div>
      <div class="col s6">
        <h5>Lapdog Status</h5>
      </div>
    </div>
    <div class="row">
      <div class="col s12" v-if="!ws">
        <div class="progress">
          <div class="indeterminate blue"></div>
        </div>
      </div>
    </div>
    <div class="stats-container" v-if="ws">
      <div class="row">
        <div class="col s2">
          Google Bucket:
        </div>
        <div class="col s4">
          <a target="_blank" v-bind:href="'https://accounts.google.com/AccountChooser?continue=https://console.cloud.google.com/storage/browser/'+ws.workspace.bucketName">
            {{ws.workspace.bucketName}}
          </a>
        </div>
        <div class="col s2">
          Execution Status:
        </div>
        <div class="col s4">
          <span v-if="!acl" class="orange-text text-darken-4">
            Pending...
          </span>
          <span v-else-if="acl.failed" class="red-text">
            <span v-if="acl.reason == 'firecloud'">
              Firecloud API Error
            </span>
            <span v-else-if="acl.reason == 'acl-read'">
              Unknown (Unable to parse workspace ACL)
            </span>
            <span v-else-if="acl.reason == 'permissions'">
              Unknown (Insufficient permissions access ACL)
            </span>
            <span v-else-if="acl.reason == 'registration'">
              Lapdog Execution not initialized
            </span>
            <span v-else>
              Unknown error: {{acl.reason}}
            </span>
          </span>
          <span v-else-if="acl.service_account" class="green-text">
            Ready to Execute
          </span>
          <span v-else-if="!acl.service_account">
            <a v-on:click="set_acl(namespace, workspace)" class='btn blue'>Enable for this workspace</a>
          </span>
        </div>
      </div>
      <div class="row">
        <div class="col s2">
          Access Level:
        </div>
        <div class="col s4">
          {{ws.accessLevel}}
        </div>
        <div class="col s2">
          Workspace Cache State:
        </div>
        <div class="col s2">
          <span v-if="!cache_state" class="amber-text text-darken-4">
            Fetching...
          </span>
          <span v-else-if="cache_state == 'up-to-date'" class="green-text">
            Online
          </span>
          <span v-else-if="cache_state == 'sync'" class="cyan-text">
            Syncing...
          </span>
          <span v-else-if="cache_state == 'outdated'" class="amber-text text-darken-3">
            Offline
          </span>
          <span v-else-if="cache_state == 'not-loaded'" class="red-text">
            Not Loaded
          </span>
        </div>
        <div class="col s2">
          <a class='btn blue' v-if="cache_state != 'sync'" v-on:click="sync_cache">Sync</a>
        </div>
      </div>
      <div class="row">
        <div class="col s2">
          Owner{{ws.owners.length > 1 ? 's' : ''}}:
        </div>
        <div class="col s4">
          {{ws.owners.join(', ')}}
        </div>
        <div class="col s6">
          <router-link class="blue btn"
            :to="{name: 'methods', params: {namespace: namespace, workspace: workspace}}">
            View/Edit Method configurations
          </router-link>
        </div>
      </div>
      <div class="row">
        <div class="col s3">
          Active Firecloud Submissions:
        </div>
        <div class="col s3">
          <a v-bind:href="'https://portal.firecloud.org/#workspaces/'+namespace+'/'+workspace+'/monitor'" target="_blank" rel="noopener">
            {{ws.workspaceSubmissionStats.runningSubmissionsCount}}
          </a>
        </div>
        <div class="col s6 execute-container">
          <a href="#submission-modal" class='btn blue modal-trigger execute-button' v-bind:class="ws.entities && ws.entities.length ? '' : 'tooltipped disabled'"
            v-bind:data-tooltip="ws.entities && ws.entities.length ? '' : 'There are no entities in this workspace'"
          >
            Execute new job
          </a>
        </div>
      </div>
    </div>
    <div class="row" v-on:click="show_attributes = !show_attributes" v-if="ws && ws.attributes && lodash.keys(ws.attributes).length">
      <div v-if="!show_attributes" class="col s6" >
        <span>
          <i class="material-icons">keyboard_arrow_right</i>
          Workspace Attributes
        </span>
      </div>
      <div v-else class="col s6">
        <span>
          <i class="material-icons">keyboard_arrow_down</i>
          Workspace Attributes
        </span>
      </div>
    </div>
    <div v-if="show_attributes">
      <!-- <div class="row">
        <div class="col s12">
          You can edit workspace attributes using the Lapdog command-line client,
          the Lapdog Python module, or on Firecloud
        </div>
      </div> -->
      <div class="row" >
        <div class="col s12 truncate">
          <table>
            <thead>
              <tr>
                <th>Attribute</th>
                <th>Value</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="key in lodash.keys(ws.attributes)" :key="key">
                <td>{{key}}</td>
                <td>
                  <a v-if="lodash.startsWith(lodash.toString(ws.attributes[key]), 'gs://')"
                    v-bind:href="'https://accounts.google.com/AccountChooser?continue=https://console.cloud.google.com/storage/browser/'+ws.attributes[key].substr(5)"
                    target="_blank" rel="noopener"
                  >
                    {{ws.attributes[key]}}
                  </a>
                  <span v-else>{{ws.attributes[key]}}</span>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
      <br>
      <br>
    </div>
    <div class="submission-container">
      <div class="row">
        <div class="col s12">
          Labdog Submissions:
        </div>
      </div>
      <!-- <div v-if="submissions" class="collection">
        <router-link v-for="sub in submissions" class="collection-item black-text"
          :to="{name: 'submission', params: {namespace:sub.namespace, workspace:sub.workspace, submission_id:sub.submission_id}}">
          <div>
            Ran <strong>{{sub.methodConfigurationName}}</strong> on <strong>{{sub.submissionEntity.entityName}}</strong> ({{sub.submission_id}})
          </div>
        </router-link>
      </div>
      <div v-else>
        <div class="progress">
          <div class="indeterminate blue"></div>
        </div>
      </div> -->

      <div v-if="submissions" class="row">
        <div class="col s12">
          <table class="highlight">
            <thead>
              <tr>
                <th>Configuration</th>
                <th>Entity</th>
                <th>Status</th>
                <th>Date</th>
                <th>Local Submission ID</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="sub in submissions">
                <td>
                  <router-link :to="{ name: 'methods', params: {namespace:namespace, workspace:workspace} }">
                    {{sub.methodConfigurationName}}
                  </router-link>
                </td>
                <td>{{sub.submissionEntity.entityName}}</td>
                <td v-bind:class="sub.status == 'Failed' || sub.status == 'Error' ? 'red-text' : (sub.status == 'Succeeded' ? 'green-text' : '')">
                  {{sub.status}}
                </td>
                <td>{{sub.submissionDate}}</td>
                <td>
                  <router-link :to="{name: 'submission', params: {namespace:sub.namespace, workspace:sub.workspace, submission_id:sub.submission_id}}">
                    {{sub.submission_id}}
                  </router-link>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
      <div v-else>
        <div class="progress">
          <div class="indeterminate blue"></div>
        </div>
      </div>

      <div class="data-viewer" v-if="ws && ws.entities && ws.entities.length">
        <hr>
        <h5>Data</h5>
        <div class="row">
          <div class="col s12">

            <!-- style="border-radius: 15px; border: 2px solid grey;" -->
            <ul class="pagination center" >
              <li v-for="etype in ws.entities" v-bind:class="active_entity == etype ? 'active' : ''"
                v-on:click.prevent="active_entity = etype"
              >
                <a href="#">{{etype.type}}s</a>
              </li>
            </ul>
            <hr>
          </div>
        </div>
        <div v-if="active_entity">
          <div class="row" v-if="active_entity.count > page_limit">
            <div class="col s12">
              <ul class="pagination center">
                <li v-bind:class="active_page == 0 ? 'disabled' : ''" v-on:click.prevent="turn_page(active_page - 1)">
                  <a href="#"><i class="material-icons">chevron_left</i></a>
                </li>
                <li v-for="page in page_range" v-on:click.prevent="turn_page(page)" v-bind:class="page == active_page ? 'active' : ''">
                  <a href="#">{{page}}</a>
                </li>
                <li v-bind:class="active_page == max_pages.length - 1 ? 'disabled' : ''" v-on:click.prevent="turn_page(active_page + 1)">
                  <a href="#"><i class="material-icons">chevron_right</i></a>
                </li>
              </ul>
            </div>
          </div>
          <div class="row">
            <div class="col s12" style="overflow-x: scroll;">
              <table v-if="entities_data">
                <thead>
                  <tr>
                    <th>{{active_entity.idName}}</th>
                    <th v-for="attr in active_entity.attributeNames">
                      {{attr}}
                    </th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="entity in entities_data">
                    <td>{{entity[active_entity.idName]}}</td>
                    <td v-for="attr in active_entity.attributeNames">
                      <a v-if="lodash.startsWith(lodash.toString(entity[attr]), 'gs://')"
                        v-bind:href="'https://accounts.google.com/AccountChooser?continue=https://console.cloud.google.com/storage/browser/'+lodash.toString(entity[attr]).substr(5)"
                        target="_blank" rel="noopener"
                      >
                        {{truncate_cell(entity[attr])}}
                      </a>
                      <span v-else>
                        {{truncate_cell(entity[attr])}}
                      </span>
                    </td>
                  </tr>
                </tbody>
              </table>
              <div v-else>
                <div class="progress">
                  <div class="indeterminate blue"></div>
                </div>
              </div>
            </div>
          </div>
          <div class="row" v-if="active_entity.count > page_limit">
            <div class="col s12">
              <ul class="pagination center">
                <li v-bind:class="active_page == 0 ? 'disabled' : ''" v-on:click.prevent="turn_page(active_page - 1)">
                  <a href="#"><i class="material-icons">chevron_left</i></a>
                </li>
                <li v-for="page in page_range" v-on:click.prevent="turn_page(page)" v-bind:class="page == active_page ? 'active' : ''">
                  <a href="#">{{page}}</a>
                </li>
                <li v-bind:class="active_page == max_pages.length - 1 ? 'disabled' : ''" v-on:click.prevent="turn_page(active_page + 1)">
                  <a href="#"><i class="material-icons">chevron_right</i></a>
                </li>
              </ul>
            </div>
          </div>
        </div>
        <div v-else>
          <div class="row">
            <div class="col s12 center">
              Select an entity type above to view
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  import axios from'axios'
  import _ from 'lodash'
  export default {
    props: ['namespace', 'workspace'],
    data() {
      return {
        lodash: _,
        ws: null,
        acl: null,
        cache_state: null,
        method_configs:null,
        entity_types: null,
        entity_field: "",
        submission_config: "",
        submission_etype: "",
        submission_expression: "",
        submission_message: "",
        submissions: null,
        expr_disabled: false,
        submit_okay: false,
        show_attributes: false,
        active_entity: null,
        entities_data: null,
        active_page: 0,
        page_limit: 15
        // entities: null
      }
    },
    created() {
      this.getWorkspace(this.namespace, this.workspace);
      this.get_acl(this.namespace, this.workspace);
      // window.$('.modal').modal();
      // this.get_configs();
      // this.get_entities(this.namespace, this.workspace);
    },
    watch: {
      active_entity(newVal, oldVal) {
        if (!newVal) return;
        this.active_page = 0;
        window.materialize.toast({
          html: "Loading "+newVal.type+'s'
        });
        this.load_data(
          newVal.type,
          0,
          this.page_limit
        )
      },
    },
    computed: {
      self_ref() {
        return this;
      },
      max_pages() {
        return _.range(0, _.floor(this.active_entity.count / this.page_limit));
      },
      page_range() {
        return _.slice(
          this.max_pages,
          _.max([0, this.active_page - 5]),
          _.min([this.max_pages.length, this.active_page + 6])
        );
      }
      // active_entity: {
      //   get() {
      //     return this._active_entity ? this._active_entity : this.ws.entities[0]
      //   },
      //   set(etype) {
      //     window.materialize.toast({html:"New etype: "+etype.type})
      //     this._active_entity = etype;
      //     window.materialize.toast({html:"New etype: "+this._active_entity.type})
      //   }
      // }
    },
    methods: {
      // set_active(etype) {
      //   this.$set(this, '_active_entity', etype);
      // },
      turn_page(page)
      {

          this.active_page = page;
          this.load_data(
            this.active_entity.type,
            (this.active_page * this.page_limit),
            ((this.active_page+1) * this.page_limit)
          );
      },
      load_data(etype, start, stop)
      {
        this.entities_data = null;
        axios.get(API_URL+'/api/v1/workspaces/'+this.namespace+'/'+this.workspace+'/entities/'+etype+'?start='+start+'&end='+stop)
          .then(response => {
            console.log("Obtained entities");
            this.entities_data = response.data;
          })
          .catch(error => {
            console.error("Unable to load entities");
            console.error(error);
            window.materialize.toast({
              html: "Unable to load entities"
            })
          })
      },
      truncate_cell(value) {
        let string_value = _.toString(value);
        if (string_value.length > 25) string_value = string_value.substr(0, 25)+"...";//"..."+string_value.substr(string_value.length - 25);
        return string_value;
      },
      preflight: _.debounce((_this) => {
        _this.submission_message = "Incomplete fields";
        if (_this.submission_config == "" || _this.submission_etype == "" || _this.entity_field == "") return;
        _this.submission_message = "-";
        console.log("Executing preflight");
        console.log(_this);
        let query = API_URL+'/api/v1/workspaces/'+_this.namespace+'/'+_this.workspace+"/preflight?";
        query += "config="+encodeURIComponent(_this.submission_config);
        query += "&entity="+encodeURIComponent(_this.entity_field);
        if (_this.submission_expression != "") query += "&expression="+encodeURIComponent(_this.submission_expression);
        if (_this.submission_etype != "") query += "&etype="+encodeURIComponent(_this.submission_etype);
        axios.post(query)
          .then(response => {
            console.log("Preflight returned");
            console.log(response);
            let result = response.data;
            _this.submit_okay = result.ok && !result.failed;
            if (_this.submit_okay) _this.submission_message = "Ready to submit " + result.workflows + " workflow(s)";
            else _this.submission_message = result.message;
          })
          .catch(response => {
            console.error("FAILED");
            console.error(response)
          })
      }, 500),
      submit_workflow() {
        let query = API_URL+'/api/v1/workspaces/'+this.namespace+'/'+this.workspace+"/execute?";
        query += "config="+encodeURIComponent(this.submission_config);
        query += "&entity="+encodeURIComponent(this.entity_field);
        if (this.submission_expression != "") query += "&expression="+encodeURIComponent(this.submission_expression);
        if (this.submission_etype != "") query += "&etype="+encodeURIComponent(this.submission_etype);
        window.materialize.toast({
          html: "Preparing job...",
          displayLength: 5000,
        })
        axios.post(query)
          .then(response => {
            console.log("Execution returned");
            console.log(response);
            let result = response.data;
            if (result.ok && !result.failed) {
              window.materialize.toast({
                html: "It may take several minutes for the submission to check in",
                displayLength: 10000,
              })
              this.$router.push({
                name: 'submission',
                params: {
                  namespace: this.namespace,
                  workspace: this.workspace,
                  submission_id: response.data.local_id
                }
              });
            }
            else {
              alert("Execute failed: "+response.data.message);
            }
          })
          .catch(response => {
            console.error("FAILED");
            console.error(response)
          })
      },
      update_expr_mode() {
        this.expr_disabled = this.extract_etype(this.submission_config) == this.submission_etype;
        console.log(this.expr_disabled);
      },
      etype_crosscheck(cfg) {
        if(this.ws) {
          for(let config in this.ws.configs)
          {
            if(cfg == (config.namespace+'/'+config.name)) {
              console.log("Etype crosscheck: " +this.submission_etype == config.rootEntityType);
              return this.submission_etype == config.rootEntityType;
            }
          }
        }
        return false
      },
      extract_etype(cfg) {
        if(this.ws) {
          for(let config in this.ws.configs)
          {
            if(cfg == (this.ws.configs[config].name)) {
              return this.ws.configs[config].rootEntityType;
            }
          }
        }
        return false
      },
      validate_entity() {
        return this.entity_field == 'h' ? 'valid' : 'invalid';
      },
      getWorkspace(namespace, workspace) {
        this.show_attributes = false;
        this.active_entity = null;
        this.entities_data = null;
        // window.$('.execute-button').tooltip('close');
        axios.get(API_URL+'/api/v1/workspaces/'+namespace+'/'+workspace)
          .then(response => {
            console.log(response.data);
            this.ws = response.data;
            this.entity_types = response.data.entities;
            this.method_configs = response.data.configs;
            window.$('.modal').modal();
            setTimeout(() => {
              window.$('.tooltipped').tooltip();
              console.log(this.ws.entities);
              console.log(window.$('.execute-button'));
              if (!(this.ws.entities && this.ws.entities.length)) window.$('.execute-container').hover(
                () => {
                  window.$('.execute-button').tooltip('open');
                },
                () => {
                  setTimeout(() => {
                    window.$('.execute-button').tooltip('close');
                  }, 100);
                }
              );
            }, 100);
            axios.get(API_URL+'/api/v1/workspaces/'+namespace+'/'+workspace+'/cache')
              .then(response => {
                console.log(response.data);
                this.cache_state = response.data;
                console.log("Fetching submissions");
                  axios.get(API_URL+'/api/v1/workspaces/'+namespace+'/'+workspace+'/submissions')
                    .then(response => {
                      console.log("Fetched submissions");
                      console.log(response.data);
                      this.submissions = response.data;
                    })
                    .catch(error => {
                      console.error("FAIL");
                      console.error(error)
                    })
              })
              .catch(error => {
                console.error("FAIL");
                console.error(error)
              })
          })
          .catch(error => {
            console.error("FAIL");
            console.error(error)
          })
      },

     get_acl(namespace, workspace) {
        axios.get(API_URL+'/api/v1/workspaces/'+namespace+'/'+workspace+'/acl')
          .then(response => {
            console.log("RESPONSE");
            console.log(response.data);
            this.acl = response.data
          })
          .catch(error => {
            console.error("FAIL")
            console.error(error)
          })
      },
      set_acl(namespace, workspace) {
        console.log("UPDATING ACL");
        this.acl = null;
         axios.post(API_URL+'/api/v1/workspaces/'+namespace+'/'+workspace+'/acl')
           .then(response => {
             console.log("RESPONSE");
             console.log(response.data);
             this.acl = response.data
           })
           .catch(error => {
             console.error("FAIL")
             console.error(error);
           })
       },

      // get_entities(namespace, workspace) {
      //   axios.get(API_URL+'/api/v1/workspaces/'+namespace+'/'+workspace+'/entities')
      //     .then(response => {
      //       this.entities = response.data.entity_types;
      //       for(let etype in this.entities.entity_types)
      //       {
      //         // this.get_cache_state(this.entities.entity_types[etype].type);
      //       }
      //     })
      //     .catch(error => {
      //       console.error("FAIL")
      //       console.error(response)
      //     })
      // },
      sync_cache() {
        this.cache_state = 'sync';
        axios.put(API_URL+'/api/v1/workspaces/'+this.namespace+'/'+this.workspace+'/cache')
          .then(response => {
            console.log(response.data);
            this.cache_state = response.data
          })
          .catch(error => {
            console.error("FAIL")
            console.error(error)
            window.materialize.toast("Failed to sync the workspace cache: "+error.response.data)
          })
      },
      get_configs() {
        axios.get(API_URL+'/api/v1/workspaces/'+this.namespace+'/'+this.workspace+'/configs')
          .then(response => {
            console.log(response.data);
            this.method_configs = response.data;
            window.$('.modal').modal();
            // this.$forceUpdate();
          })
          .catch(error => {
            console.error("FAIL");
            console.error(error)
          })
      }
      // get_cache_state(etype) {
      //   axios.get(API_URL+'/api/v1/workspaces/'+this.namespace+'/'+this.workspace+'/cache/'+etype)
      //     .then(response => {
      //       console.log("Fetched cache state for "+etype);
      //       this.cache_state[etype] = response.data;
      //       console.log(this.cache_state);
      //     })
      //     .catch(error => {
      //       console.error("FAIL")
      //       console.error(response)
      //     })
      // }
    },
    beforeRouteUpdate(to, from, next) {
      this.ws = null;
      this.acl = null;
      this.entities = null;
      this.method_configs = null;
      this.submit_okay = false;
      this.submission_message = "";
      this.entity_field = "";
      this.submission_expression = "";
      this.submissions = null;
      this.active_entity = null;
      this.getWorkspace(to.params.namespace, to.params.workspace);
      this.get_acl(to.params.namespace, to.params.workspace);
      // this.get_configs();
      next();
    }
  }
</script>

<style lang="css">
  ul.pagination > li.active {
    background: #1e88e5;
  }

  div.data-viewer td {
    font-size: 0.9em;
    padding: 5px;
  }
</style>
