<!-- The <push-server-sk> custom element declaration.

Displays the server configurations, along with the ability to modify application selections.

  Attributes:
    servers: Map of server names to the apps and their versions. Such as:

      [
        {
          Name: 'skia-monitoring',
          Installed: [
            'pull:jcgregorio@jcgregorio.cnc.corp.google.com:2014-12-08T02:09:58Z:79f6b17ea316c5d877f4f1e3fa9c7a4ea950916c.deb',
            'logserver/',
          ]
        },
        {
          Name: 'skia-testing-b',
          Installed: []
        }
      ]

      Note that an entry in Installed can either be a full package path, or
      just a shortened '{appname}/' version which indicates which app is
      expected but also signals that no specific release package has been
      chosen or deployed yet.

    packages: Map of app names to the list of available versions, sorted from newest to oldest. Such as:

      {
        'pull': [
          {
            Name: 'pull:jcgregorio@jcgregorio.cnc.corp.google.com:2014-12-08T02:09:58Z:79f6b17ea316c5d877f4f1e3fa9c7a4ea950916c.deb',
            Hash: '79f6b17ea316c5d877f4f1e3fa9c7a4ea950916c',
            UserID: 'jcgregorio@jcgregorio.cnc.corp.google.com',
            Built: '2014-12-08T02:09:58Z',
            Dirty: true,
            Note: 'some reason for a push'
          },
          {
            Name: 'pull:jcgregorio@jcgregorio.cnc.corp.google.com:2014-12-08T01:39:47Z:323894732847ace1289a9a90192123213.deb',
            Hash: '323894732847ace1289a9a90192123213',
            UserID: 'jcgregorio@jcgregorio.cnc.corp.google.com',
            Built: '2014-12-08T01:39:47Z',
            Dirty: false,
            Note: 'no reason'
          }
        ],
        'logserver': [
        ]
      }

  Events:
    'change-package'
        A 'change-package' event is generated when the user selects a package to push.
        The change event has the following attributes:

          event.detail.server - The name of the server.
          event.detail.name   - The full name of the package to push.

  Methods:
    setConfig(servers, packages)

  Clicking on an app brings up a selection dialog with all available options,
  the current one already selected. A selection will update and push.
-->

<link rel="import" href="/res/common/imp/confirm-dialog-sk.html">

<dom-module id="push-server-sk">
  <style type="text/css" media="screen">
    table {
      border-spacing: 0;
    }

    h2 {
      color: #33A02C;
      margin-left: 1em;
      display: inline;
      padding-right: 1em;
    }

    h3 {
      margin-left: 1em;
      color: #1f78b4;
      display: inline;
    }

    .appName {
      padding-right: 1em;
      width: 10em;
    }

    td iron-icon {
      padding-right: 1em;
    }

    paper-button {
      color: #1f78b4;
    }

    paper-button:hover {
      background: #eee;
    }

    .service {
      width: 14em;
    }

    .status,
    .uptime {
      width: 10em;
    }

    .uptime {
      font-family: monospace;
    }

    tr:nth-child(2n+1) {
      background: #eee;
    }
  </style>
  <template>
    <confirm-dialog-sk id="reboot_confirm_dialog"></confirm-dialog-sk>

    <div on-tap="editClicked">
      <h3>Displaying {{displayedCount}} out of {{servers.length}} servers</h3>
      <br/><br/><br/>
      <template is="dom-repeat" items="{{servers}}" as=server rendered-item-count="{{displayedCount}}"
                filter={{_filterServers(filterText)}}>
        <section>
          <h2>{{server.Name}}</h2>
          <paper-button raised data-action="start"
                        data-name="reboot.target"
                        data-server$="[[server.Name]]">Reboot</paper-button>
          [<a target=_blank href$="{{monURI(server.Name)}}">mon</a>]
          [<a target=_blank href$="{{logsURI(server.Name)}}">logs</a>]
          <table>
            <template is="dom-repeat" items="{{server.Installed}}" as="installed">
              <tr>
                <td>
                  <paper-button class=application
                    data-server$="{{server.Name}}" data-name$="{{installed}}" data-app$="{{prefixOf(installed)}}"><iron-icon icon="create" title="Edit which package is installed."></iron-icon></paper-button>
                </td>
                <td><div class=appName>{{prefixOf(installed)}}</div></td>
                <td><span class=appName><a href$="https://github.com/google/skia-buildbot/compare/{{fullHash(installed)}}...HEAD">{{short(installed)}}</a></span></td>
                <td><iron-icon icon$="{{alarmIfNotLatest(installed)}}" title="Out of date."></iron-icon></td>
                <td><iron-icon icon$="{{warnIfDirty(installed)}}" title="Uncommited changes when the package was built."></iron-icon></td>
                <td><a href$="{{logsFullURI(server.Name,installed)}}">logs</a></td>
                <td>
                  <table>
                    <template is="dom-repeat" items="{{servicesOf(installed)}}" as="service">
                      <tr>
                        <systemd-unit-status-sk machine="{{server.Name}}" service="{{service}}"></systemd-unit-status-sk>
                      </tr>
                    </template>
                  </table>
                </td>
              </tr>
            </template>
          </table>
        </section>
      </template>
      <push-selection-sk id=extChooser></push-selection-sk>
    </div>
  </template>
</dom-module>
<script>
  Polymer({
    is: "push-server-sk",

    properties: {
      servers: {
        type: Array,
        value: function() { return []; },
      },
      packages: {
        type: Array,
        value: function() { return []; },
      },
      ip: {
        type: Object,
        value: function() { return {}; },
      },
      packageLookup: {
        type: Object,
        value: function() { return {}; },
      },
      server: {
        type: String,
        value: '',
      },
      filterText: {
        type: String,
        value: '',
      },
      displayedCount: {
        type: Number,
        value: 0,
      }
    },

    ready: function() {
      // When the push-selection-sk dialog notifies us of a selection
      // we fill in some more details and pass that along as another
      // CustomEvent.
      this.$.extChooser.addEventListener('change-package', function(e) {
        var detail = {
          name:   e.detail.name,
          server: this.server
        };
        this.dispatchEvent(new CustomEvent('change-package', {detail: detail}));
      }.bind(this));
    },

    editClicked: function(e) {
      var button = sk.findParent(e.target, "PAPER-BUTTON");
      if (button == null || !button.dataset.server) {
        return
      }
      this.server = button.dataset.server;
      if (button.dataset.action) {
        this.$.reboot_confirm_dialog
          .open("Proceed with rebooting " + this.server + "?")
          .then(function() {
            var detail = {
              machine: button.dataset.server,
              name: button.dataset.name,
              action: button.dataset.action,
            };
            this.dispatchEvent(new CustomEvent('unit-action', {detail: detail, bubbles: true}));
          }.bind(this));
      } else {
        var id = button.dataset.name;
        var app = button.dataset.app;
        if (app != "") {
          this.$.extChooser.choices = this.packages[app];
          this.$.extChooser.choice = id;
          this.$.extChooser.toggle();
        }
      }
    },

    setConfig: function(servers, packages, ip) {
      this.servers = servers;
      this.packages = packages;
      this.ip = ip;
      for (appName in this.packages) {
        var that = this;
        var latest = true;
        this.packages[appName].forEach(function(details) {
          that.packageLookup[details.Name] = details;
          that.packageLookup[details.Name].Latest = latest;
          latest = false;
        });
      }
    },

    _filterServers: function(filterText) {
      return function(server) {
        var findMatchingServers = true;
        var filterBy = filterText;
        if (filterBy.startsWith('^')) {
          findMatchingServers = false;
          filterBy = filterBy.substring(1);
        }
        if (filterBy == "") {
          return true;
        }
        // Try to match the server name prefix.
        if (server.Name.indexOf(filterBy) == 0) {
          return findMatchingServers;
        }
        // Now try to match the prefix of all server name tokens.
        var tokens = server.Name.split('-');
        for (var tokenIndex in tokens) {
          if (tokens[tokenIndex].indexOf(filterBy) == 0) {
            return findMatchingServers;
          }
        }
        // Now try to match the app name prefix.
        for (var installedIndex in server.Installed) {
          var installed = server.Installed[installedIndex];
          var appName = this.prefixOf(installed);
          if (appName.indexOf(filterBy) == 0) {
            return findMatchingServers;
          }
        }
        return !findMatchingServers;
      }.bind(this);
    },

    // prefixOf is a helper used in templates that returns all the text
    // that appears before the first '/'.
    prefixOf: function(s) {
      return s.split('/')[0];
    },

    // fullHash is a utility function used in templates to extract the full git hash
    // from a package name.
    fullHash: function(s) {
      return s.slice(s.length-44, s.length-4)
    },

    // short is a utility function used in templates to truncate strings.
    short: function(s) {
      return this.fullHash(s).slice(0, 6);
    },

    alarmIfNotLatest: function(installed) {
      if (!this.packageLookup[installed]) {
        return ' '; // Don't return an empty string here, to force the icon to change.
      } else {
        return this.packageLookup[installed].Latest ? ' ' : 'alarm';
      }
    },

    warnIfDirty: function(installed) {
      if (!this.packageLookup[installed]) {
        return ' '; // Don't return an empty string here, to force the icon to change.
      } else {
        return this.packageLookup[installed].Dirty ? 'warning' : ' ';
      }
    },

    servicesOf: function(installed) {
      var p = this.packageLookup[installed];
      if (!p) {
        return [];
      }
      return p.Services;
    },

    monURI: function(name) {
      return "https://" + name + "-10000-proxy.skia.org";
    },

    logsURI: function(name) {
      return "https://console.cloud.google.com/logs/viewer?project=google.com:skia-buildbots&minLogLevel=200&expandAll=false&resource=logging_log%2Fname%2F" + name;
    },

    logsFullURI: function(name, installed) {
      var 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;
    },

  });
</script>
