import 'elements-sk/styles/buttons'
import 'elements-sk/icon/alarm-icon-sk'
import 'elements-sk/icon/create-icon-sk'
import 'elements-sk/icon/warning-icon-sk'
import 'elements-sk/spinner-sk'
import 'elements-sk/error-toast-sk'
import { errorMessage } from 'elements-sk/errorMessage'

import '../../../infra-sk/modules/app-sk'
import '../../../infra-sk/modules/confirm-dialog-sk'
import '../../../infra-sk/modules/systemd-unit-status-sk'
import '../../../infra-sk/modules/login-sk'

import { $$ } from 'common-sk/modules/dom'
import { fromObject } from 'common-sk/modules/query'
import { jsonOrThrow } from 'common-sk/modules/jsonOrThrow'
import { stateReflector } from 'common-sk/modules/stateReflector'

import { define } from 'elements-sk/define'
import { html, render } from 'lit-html'

import '../push-selection-sk'

// How often we should poll for status updates.
const UPDATE_MS = 5000;

// Utility functions for templating.
const monURI = (name) => `https://${name}-10000-proxy.skia.org`;
const logsURI = (name) => `https://console.cloud.google.com/logs/viewer?project=google.com:skia-buildbots&minLogLevel=200&expandAll=false&resource=logging_log%2Fname%2F${name}`;
const prefixOf = (s) => s.split('/')[0];
const fullHash = (s) => s.slice(s.length-44, s.length-4);
const shorten = (s) => fullHash(s).slice(0, 6);

const alarmVisibility = (ele, installed) => {
  if (!ele._packageLookup[installed]) {
    return 'invisible'
  } else {
    return ele._packageLookup[installed].Latest ? 'invisible' : '';
  }
};

const dirtyVisibility = (ele, installed) => {
  if (!ele._packageLookup[installed]) {
    return 'invisible'
  } else {
    return ele._packageLookup[installed].Dirty ? '' : 'invisible';
  }
};

const logsFullURI = (name, installed) => {
  let app = installed.split('/')[0];
  return `https://console.cloud.google.com/logs/viewer?project=google.com:skia-buildbots&minLogLevel=200&expandAll=false&resource=logging_log%2Fname%2F${ name }&logName=projects%2Fgoogle.com:skia-buildbots%2Flogs%2F${ app }`;
};

const servicesOf = (ele, installed) => {
  let p = ele._packageLookup[installed];
  return p ? p.Services : [];
};

const listServices = (ele, server, installed) => servicesOf(ele, installed).map(service => {
  return html`<systemd-unit-status-sk machine='${server.Name}' .value=${ele._state.status[server.Name + ':' + service]} ></systemd-unit-status-sk>`;
});

const listApplications = (ele, server) => server.Installed.map(installed => html`
<div class=applicationRow>
  <button class=application data-server='${server.Name}' data-name='${installed}' data-app='${prefixOf(installed)}' @click=${ele._startChoose}><create-icon-sk title='Edit which package is installed.'></create-icon-sk></button>
  <warning-icon-sk class='${dirtyVisibility(ele, installed)}' title='Out of date.'></warning-icon-sk>
  <alarm-icon-sk class='${alarmVisibility(ele, installed)}' title='Uncommited changes when the package was built.'></alarm-icon-sk>
  <div class=serviceName><a href='https://github.com/google/skia-buildbot/compare/${fullHash(installed)}...HEAD'>${shorten(installed)}</a></div>
  <div class=logs><a href='${logsFullURI(server.Name, installed)}'>logs</a></div>
  <div>
    ${listServices(ele, server, installed)}
  </div>
  <div class=appName>${prefixOf(installed)}</div>
</div>`);

// Only display a server if it matches the current filter.
const classMatchFilter = (ele, server) => {
  let search = ele._query.search;
  // Short-circuit the most common case.
  if (!search) {
    return '';
  }
  return (server.Name.includes(search) || server.Installed.find(installed => prefixOf(installed).includes(search))) ? '' : 'hidden';
};

const listServers = (ele) => ele._state.servers.map(server => html`
<section class='${classMatchFilter(ele, server)}'>
  <h2>${server.Name}</h2>
  <button class=reboot raised data-action='start' data-name='reboot.target' data-server='${server.Name}' @click=${ele._reboot}>Reboot</button>
  [<a target=_blank href='${monURI(server.Name)}'>mon</a>]
  [<a target=_blank href='${logsURI(server.Name)}'>logs</a>]
  <div class=appContainer>
    ${listApplications(ele, server)}
  </div>
</section>`);

const template = (ele) => html`
<app-sk>
  <header><h1>Push</h1> <login-sk></login-sk></header>
  <main @unit-action=${(e) => ele._unitAction(e.detail)}>
    <section class=controls>
      <button id=refresh @click=${ele._refreshClick}>Refresh Packages</button>
      <spinner-sk id=spinner></spinner-sk>
      <label>Filter servers/apps: <input type=text @input=${ele._filterInput} value='${ele._query.search}'></input></label>
    </section>
    ${listServers(ele)}
  </main>
  <footer>
    <error-toast-sk></error-toast-sk>
    <push-selection-sk id='push-selection' @package-change=${ele._packageChange}></push-selection-sk>
    <confirm-dialog-sk id='confirm-dialog'></confirm-dialog-sk>
  </footer>
</app-sk>`;

/** <code>push-app-sk</code> custom element declaration.
 *
 * <p>
 *   The main element for the push application.
 * </p>
 */
class PushAppSk extends HTMLElement {
  constructor() {
    super();
    // Populated from push/main AllUI type.
    this._state = {
      servers: [],
      packages: {},
      status: {},
    };

    // Bits of state that get reflected to/from the URL query string.
    this._query = {
      // The current value of the filter text box.
      search: '',
    }
  }

  connectedCallback() {
    this._render();
    this._spinner = $$('#spinner');
    this._push_selection = $$('#push-selection');
    this._chosenServer = '';
    fetch('/_/state').then(jsonOrThrow).then(state => {
      this._setState(state);
      this._updateStatus();
      this._render();
    }).catch(errorMessage);
    this._stateHasChanged = stateReflector(() => this._query, (query) => {
      this._query = query;
      this._render();
    });
  }

  _render() {
    render(template(this), this, {eventContext: this});
  }

  // Called when the user presses the button to choose a different package version.
  // Presents a dialog of available package versions to choose from.
  _startChoose(e) {
    let target = e.target;
    if (target.nodeName !== 'BUTTON') {
      target = target.parentElement;
    }
    this._chosenServer = target.dataset.server;
    let choices = this._state.packages[target.dataset.app];
    let chosen = choices.findIndex(choice => choice.Name === target.dataset.name);
    this._push_selection.choices = choices;
    this._push_selection.chosen = chosen;
    this._push_selection.show();
  }

  // Called when the user has actually made a selection from the dialog that
  // was displayed when _startChoose() was called.
  _packageChange(e) {
    this._push_selection.hide();
    this._spinner.active = true;
    let body = {
      name: e.detail.name,
      server: this._chosenServer,
    }
    fetch('/_/state', {
      method: 'POST',
      body: JSON.stringify(body),
      headers: {
        'content-type': 'application/json'
      },
      credentials: 'include',
    }).then(jsonOrThrow).then(state => {
      this._spinner.active = false;
      this._setState(state);
    }).catch(err => {
      this._spinner.active = false;
      errorMessage(err);
    });
  }

  _reboot(e) {
    let button = e.target;
    $$('#confirm-dialog').open(`Proceed with rebooting ${ button.dataset.server }?`).then(() => {
      this._unitAction({
        machine: button.dataset.server,
        name: button.dataset.name,
        action: button.dataset.action,
      });
    });
  }

  // Perform an action on a systemd unit. The 'detail' must have a 'name',
  // 'action', and 'machine' properties.
  _unitAction(detail) {
    this._spinner.active = true;
    fetch('/_/change?' + fromObject(detail), {
      method: 'POST',
      credentials: 'include',
    }).then(jsonOrThrow).then(json => {
      this._spinner.active = false;
      errorMessage(json.result);
    }).catch(err => {
      this._spinner.active = false;
      errorMessage(err);
    });
  }

  // Set the new state of push.
  _setState(value) {
    this._state = value;
    this._packageLookup = {};
    for (let appName in this._state.packages) {
      let latest = true;
      this._state.packages[appName].forEach(details => {
        this._packageLookup[details.Name] = details;
        this._packageLookup[details.Name].Latest = latest;
        latest = false;
      });
    }
    this._render();
  }

  // Get the new status from the push server.
  _updateStatus() {
    fetch('/_/status').then(jsonOrThrow).then(json => {
      this._state.status = json;
      this._render();
      window.setTimeout(() => this._updateStatus(), UPDATE_MS);
    }).catch(err => {
      errorMessage(err)
      window.setTimeout(() => this._updateStatus(), UPDATE_MS);
    });
  }

  // Refresh the full state from push, not just the status.
  _refreshClick(e) {
    this._spinner.active = true;
    fetch('/_/state?refresh=true').then(jsonOrThrow).then(json => {
      this._setState(json);
      this._spinner.active = false;
    }).catch(err => {
      this._spinner.active = false;
      errorMessage(err);
    });
  }

  // Called when the user edits the filter text box.
  _filterInput(e) {
    this._query.search = e.target.value;
    this._stateHasChanged();
    this._render();
  }

}

define('push-app-sk', PushAppSk);
