var nightlies = {};
var tinderboxen = {};

const TIMESCALE = 6;
const BOXWIDTH = 100;
const START = Date.now() / 1000;

function isPerfBox(name) {
  return name.indexOf(" perf ") >= 0 || name.indexOf(" talos ") >= 0;
}

function isNightlyBox(name) {
  return name.indexOf("Nightly") >= 0;
}

function guessName(name) {
  var parts = name.split(" ");
  for (var j = 0; j < parts.length; j++) {
    if (parts[j].indexOf("-") >= 0)
      return parts[j];
  }
  return name;
}

function updatePerfResults(box, dataset, build) {
  dataset.build = build;
  alert("error");
}

function createResultsBox(box, build, targetdiv) {
  var div = document.createElement("div");
  targetdiv.appendChild(div);
  div.setAttribute("title", box.name);
  var icon = document.createElement("div");
  div.appendChild(icon);
  icon.className = "icon";
  var p = document.createElement("p");
  div.appendChild(p);
  div.className = "testresult " + build.getStatus();
  if (build.getName().indexOf(" talos ") >= 0) {
    div.className += " talos";
    p.appendChild(document.createTextNode("Talos"));
  }
  else if (build.getName().indexOf(" perf ") >= 0) {
    div.className += " perf";
    p.appendChild(document.createTextNode("Perf"));
  }
  else {
    div.className += " test";
    p.appendChild(document.createTextNode("Unit Test"));
  }
}

function addPerfResults(box, dataset, build) {
  dataset.build = build;
  dataset.inputSet.associatedBuilds.push(dataset);
  dataset.div = createResultsBox(box, build, dataset.inputSet.div);

  updateBuild(nightlies[build.getPlatform()], dataset.inputSet, dataset.inputSet.build);
}

function determineStatus(dataset) {
  var status = dataset.build.getStatus();
  if (status == "busted")
    return status;

  for (var i = 0; i < dataset.associatedBuilds.length; i++) {
    if (dataset.associatedBuilds[i].build.getStatus() == "busted")
      return "busted";
    if (dataset.associatedBuilds[i].build.getStatus() == "testfailed")
      status = "testfailed";
  }

  return status;
}

function addBuildLinks(build, div) {
  var newdiv = document.createElement("div");
  if (div.firstChild)
    div.insertBefore(newdiv, div.firstChild);
  else
    div.appendChild(newdiv);
  newdiv.className = "buildlogs " + build.getStatus();
  var p = document.createElement("p");
  newdiv.appendChild(p);
  var a = document.createElement("a");
  p.appendChild(a);
  a.setAttribute("href", "http://tinderbox.mozilla.org/showlog.cgi?log=Firefox/" + build.getLogFile());
  a.appendChild(document.createTextNode("Log"));
}

function updateBuild(box, dataset, build) {
  if ((dataset.build.getStatus() == "building") &&
      (build.getStatus() != "building")) {
    addBuildLinks(build, dataset.div);
    if (build.getTests().length > 0)
      createResultsBox(box, build, dataset.div);
  }
  dataset.build = build;
  dataset.div.className = "build " + determineStatus(dataset);
}

function addBuild(box, dataset, build) {
  dataset.build = build;
  var div = document.createElement("div");
  box.div.lastChild.appendChild(div);
  div.className = "build " + determineStatus(dataset);
  var end = build.getEndTime();
  if (end == build.getStartTime())
    end = START;
  div.style.top = parseInt((START - end) / TIMESCALE) + "px";
  div.style.height = parseInt((end - build.getStartTime()) / TIMESCALE) + "px";
  dataset.div = div;

  if (build.getStatus() != "building") {
    addBuildLinks(build, div);
    if (build.getTests().length > 0)
      createResultsBox(box, build, div);
  }
}

function updateHeader(box) {
  var status = "header";
  if (box.newest)
    status += " " + determineStatus(box.newest);
  box.div.firstChild.className = status;
}

function addHeader(box) {
  var div = document.createElement("div");
  document.getElementById(box.platform).appendChild(div);
  box.div = div;
  div.id = box.name;
  div.className = "tinderbox " + box.platform;
  var header = document.createElement("div");
  div.appendChild(header);
  var status = "header";
  if (box.newest)
    status += " " + determineStatus(box.newest);
  header.className = status;
  var builds = document.createElement("div");
  div.appendChild(builds);
  builds.className="builds";

  var name = document.createElement("p");
  header.appendChild(name);
  name.appendChild(document.createTextNode(box.name));
}

function processData(data) {
  var tree = new Tree(data);

  var builds = tree.getBuilds();
  var perfbuilds = [];

  var results = "";
  var column = 0;
  for (var i = 0; i < builds.length; i++) {
    var name = builds[i].getName();
    if (!(name in tinderboxen)) {
      var realname = guessName(name);
      var info = name.replace(realname, "").replace(builds[i].getPlatform(), "");
      tinderboxen[name] = {
        name: realname,
        platform: builds[i].getPlatform(),
        newest: null,
        datasets: []
      };
      if (isPerfBox(name)) {
        info = info.replace("talos", "").replace("perf", "");
      }
      else {
        if (isNightlyBox(name)) {
          info = info.replace("Nightly", "");
          nightlies[builds[i].getPlatform()] = tinderboxen[name];
        }
        tinderboxen[name].column = column++;
      }
      info = info.replace(/\s+/g, " ");
      tinderboxen[name].info = info;
      if (!isPerfBox(name))
        addHeader(tinderboxen[name]);
    }
    
    // Have we seen this build before?
    var box = tinderboxen[name];
    var dataset = box.datasets[builds[i].getStartTime()];
    if (dataset) {
      // Has the status changed?
      if (dataset.build.getStatus() != builds[i].getStatus()) {
        if (isPerfBox(name)) {
          updatePerfResults(box, dataset, builds[i]);
        }
        else {
          updateBuild(box, dataset, builds[i]);
          if (box.newest == dataset) {
            updateHeader(box);
          }
          else if (builds[i].getStatus() != "building") {
            if ((!box.newest) || (box.newest.build.getStartTime() < builds[i].getStartTime())) {
              box.newest = dataset;
              updateHeader(box);
            }
          }
        }
      }
    }
    else if (isPerfBox(name)) {
      perfbuilds.push(builds[i]);
    }
    else {
      dataset = {
        associatedBuilds: []
      };
      box.datasets[builds[i].getStartTime()] = dataset;
      addBuild(box, dataset, builds[i]);
      if (builds[i].getStatus() != "building") {
        if ((!box.newest) || (box.newest.build.getStartTime() < builds[i].getStartTime())) {
          box.newest = dataset;
          updateHeader(box);
        }
      }
    }
  }
  
  for (var i = 0; i < perfbuilds.length; i++) {
    var target = nightlies[perfbuilds[i].getPlatform()].datasets[perfbuilds[i].getStartTime()];
    if (target) {
      dataset = {
        inputSet: target
      };
      var box = tinderboxen[perfbuilds[i].getName()];
      box.datasets[perfbuilds[i].getStartTime()] = dataset;
      addPerfResults(box, dataset, perfbuilds[i]);
    }
  }
}

const DATESTEP = 15 * 60 * 1000;
const DATESKIP = 10 * 60 * 1000;

function Startup() {
  processData(tinderbox_data);
  var p = document.createElement("p");
  document.getElementById("times").appendChild(p);
  p.className = "timeindex";
  p.appendChild(document.createTextNode((new Date(START)).toLocaleTimeString()));
  
  var pos = Math.floor((START - DATESKIP) / DATESTEP) * DATESTEP;
  var min = START - 12 * 60 * 60 * 1000;
  while (pos >= min) {
    p = document.createElement("p");
    document.getElementById("times").appendChild(p);
    p.className = "timeindex";
    p.style.top = parseInt(((START - pos) / 1000) / TIMESCALE) + "px";
    p.appendChild(document.createTextNode((new Date(pos)).toLocaleTimeString()));
    pos -= DATESTEP;
  }
}


