<html>
<head>
  <title>job-search-sk demo</title>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
  <script src="/res/common/js/common.js"></script>
  <script src="/res/imp/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
  <script type="text/javascript" src="job-search-sk-demo.json"></script>
  <script type="text/javascript" charset="utf-8">
    // Mock out sk.get and so we can fake a response from the server.
    sk.get = function(url) {
      return new Promise(function (resolve, reject) {
        if (url.indexOf("/json/jobs/search") != -1) {
          var rv = jobs;
          var idx = url.indexOf("?");
          var query = "";
          if (idx != -1) {
            idx++; // To trim the "?"
            if (idx < url.length) {
              query = url.substring(idx);
            }
          }
          if (query != "") {
            var params = sk.query.toParamSet(query);
            var rv = [];
            for (var i = 0; i < jobs.length; i++) {
              var job = jobs[i];
              var match = true;
              for (var key in params) {
                var vals = params[key];
                if (key == "time_start") {
                  var jobTime = (new Date(job.created)).getTime();
                  var startTime = (new Date(vals[0])).getTime();
                  if (jobTime < startTime) {
                    match = false;
                    break;
                  }
                } else if (key == "time_end") {
                  var jobTime = (new Date(job.created)).getTime();
                  var endTime = (new Date(vals[0])).getTime();
                  if (jobTime >= endTime) {
                    match = false;
                    break;
                  }
                } else {
                  var anyMatch = false;
                  var jobVal = job[key].toString();
                  for (var j = 0; j < vals.length; j++) {
                    if (jobVal == vals[j]) {
                      anyMatch = true;
                      break;
                    }
                  }
                  if (!anyMatch) {
                    match = false;
                    break;
                  }
                }
              }
              if (match) {
                rv.push(job);
              }
            }
          }
          resolve(JSON.stringify(rv));
        } else if (url == "/loginstatus/") {
          resolve('{"Email":"user@google.com","LoginURL":"https://accounts.google.com/"}');
        } else {
          reject("Unknown url " + url);
        }
      });
    };
    sk.post = function(url) {
      return new Promise(function (resolve, reject) {
        for (var i = 0; i < jobs.length; i++) {
          var job = jobs[i];
          if (url.indexOf(job.id) != -1) {
            job.status = "CANCELED";
            job.finished = (new Date()).toISOString();
            resolve(JSON.stringify(job));
          }
        }
        reject("Unknown url " + url);
      });
    };

  </script>
  <link rel="import" href="job-search-sk.html">
  <link rel="import" href="/res/common/imp/error-toast-sk.html">
  <link rel="import" href="/res/common/imp/login.html">
  <link rel="import" href="/res/imp/bower_components/paper-toggle-button/paper-toggle-button.html" />
</head>
<body>
  <dom-module id="job-search-sk-demo">
    <template>
      <job-search-sk
          recent_repos="[[recent_repos]]"
          recent_servers="[[recent_servers]]"
          valid_statuses="[[valid_statuses]]"
          ></job-search-sk>
    </template>
    <script>
      Polymer({
        is: 'job-search-sk-demo',

        properties: {
            recent_repos: {
              type: Array,
            },
            recent_servers: {
              type: Array,
            },
            valid_statuses: {
              type: Array,
            },
        },

        ready: function() {
          var recent_repos = new Set();
          var recent_servers = new Set();
          var valid_statuses = new Set();
          for (var i = 0; i < jobs.length; i++) {
            var job = jobs[i];
            recent_repos.add(job.repo);
            if (job.server) {
              recent_servers.add(job.server);
            }
            valid_statuses.add(job.status);
          }
          this.set("recent_repos", Array.from(recent_repos));
          this.set("recent_servers", Array.from(recent_servers));
          this.set("valid_statuses", Array.from(valid_statuses));
        },
      });
    </script>
  </dom-module>

  <login-sk style="display:none"></login-sk>
  <h1>job-search-sk demo</h1>
  <job-search-sk-demo></job-search-sk-demo>
  <error-toast-sk></error-toast-sk>
</body>
</html>
