<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Compare Results - Web Platform Test</title>
    <link rel="stylesheet" href="css/bulma-0.7.5/bulma.min.css" />
    <link rel="stylesheet" href="css/fontawesome-5.7.2.min.css" />
    <script src="lib/utils.js"></script>
    <script src="lib/wave-service.js"></script>
    <script src="lib/ui.js"></script>
    <style>
      body {
        margin: 0;
        padding: 0;
        width: 100vw;
        height: 100vh;
        display: flex;
        justify-content: center;
        font-family: "Noto Sans", sans-serif;
        overflow-y: auto;
        overflow-x: hidden;
        background-color: white;
        color: #000;
      }

      .site-logo {
        max-width: 300px;
        margin-left: -15px;
      }

      .content {
        width: 1000px;
      }

      .header {
        display: flex;
        margin: 50px 0 30px 0;
      }

      .header :first-child {
        flex: 1;
      }

      .session-header {
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: pointer;
      }

      .session-header div {
        padding: 5px;
        font-weight: bold;
      }

      .session-header:hover div {
        text-decoration: underline;
      }
    </style>
  </head>
  <body>
    <script>
      window.onload = () => {
        let { tokens, reftokens } = utils.parseQuery(location.search);
        tokens = tokens ? tokens.split(",") : [];
        const refTokens = reftokens ? reftokens.split(",") : [];
        if (tokens) {
          WaveService.readStatus(function(config) {
            comparisonUi.state.reportsEnabled = config.reportsEnabled;
            comparisonUi.render();
          });
          WaveService.addRecentSessions(tokens);
          WaveService.addRecentSessions(refTokens);
          comparisonUi.state.tokens = tokens;
          comparisonUi.state.refTokens = refTokens;
          comparisonUi.render();
          comparisonUi.refreshData();
        }
      };

      const comparisonUi = {
        state: {
          tokens: [],
          refTokens: [],
          sessions: {}
        },
        refreshData: () => {
          const { tokens, refTokens } = comparisonUi.state;
          const allTokens = tokens.slice();
          refTokens
            .filter(token => allTokens.indexOf(token) === -1)
            .forEach(token => allTokens.push(token));

          WaveService.readMultipleSessions(allTokens, configurations => {
            const sessions = {};
            configurations.forEach(
              details => (sessions[details.token] = details)
            );
            comparisonUi.state.sessions = sessions;

            WaveService.readResultComparison(tokens, results => {
              comparisonUi.state.results = results;
              comparisonUi.renderApiResults();
            });

            const sessionsReferenceTokens = [];
            configurations.forEach(({ referenceTokens }) =>
              referenceTokens
                .filter(token => refTokens.indexOf(token) === -1)
                .filter(token => sessionsReferenceTokens.indexOf(token) === -1)
                .forEach(token => sessionsReferenceTokens.push(token))
            );

            sessionsReferenceTokens.forEach(token =>
              comparisonUi.state.refTokens.push(token)
            );

            WaveService.readMultipleSessions(
              sessionsReferenceTokens,
              configurations => {
                const { sessions } = comparisonUi.state;
                configurations.forEach(
                  details => (sessions[details.token] = details)
                );
                comparisonUi.renderDetails();
              }
            );
          });
        },
        openResultsOverview() {
          location.href = WEB_ROOT + "overview.html";
        },
        render() {
          const comparisonView = UI.createElement({
            className: "content",
            style: "margin-bottom: 40px;",
            children: [
              {
                className: "header",
                children: [
                  {
                    children: [
                      {
                        element: "img",
                        src: "res/wavelogo_2016.jpg",
                        className: "site-logo"
                      }
                    ]
                  },
                  {
                    className: "button is-dark is-outlined",
                    onClick: comparisonUi.openResultsOverview,
                    children: [
                      {
                        element: "span",
                        className: "icon",
                        children: [
                          {
                            element: "i",
                            className: "fas fa-arrow-left"
                          }
                        ]
                      },
                      {
                        text: "Results Overview",
                        element: "span"
                      }
                    ]
                  }
                ]
              },
              {
                id: "header",
                children: [
                  { className: "title", text: "Comparison" },
                  { id: "controls" }
                ]
              },
              { id: "details" },
              { id: "api-results" }
            ]
          });

          const root = UI.getRoot();
          root.innerHTML = "";
          root.appendChild(comparisonView);
          comparisonUi.renderDetails();
          comparisonUi.renderApiResults();
        },
        renderDetails() {
          const detailsView = UI.createElement({
            style: "margin-bottom: 20px"
          });

          const { refTokens } = comparisonUi.state;
          const detailsTable = UI.createElement({
            element: "table",
            children: {
              element: "tbody",
              children: [
                {
                  element: "tr",
                  id: "reference-sessions"
                }
              ]
            }
          });
          detailsView.appendChild(detailsTable);

          const details = UI.getElement("details");
          details.innerHTML = "";
          details.appendChild(detailsView);
          comparisonUi.renderReferenceSessions();
        },
        renderReferenceSessions() {
          const { sessions, refTokens } = comparisonUi.state;
          if (!refTokens || refTokens.length === 0) return;
          if (!Object.keys(sessions) || Object.keys(sessions).length === 0)
            return;
          const referenceSessions = refTokens.map(token => sessions[token]);
          const referenceSessionsTarget = UI.getElement("reference-sessions");
          referenceSessionsTarget.innerHTML = "";

          const referenceSessionsLabel = UI.createElement({
            element: "td",
            text: "Reference Sessions:",
            style: "width: 175px"
          });
          referenceSessionsTarget.appendChild(referenceSessionsLabel);

          const referenceSessionsList = UI.createElement({ element: "td" });
          referenceSessions.forEach(session => {
            const { token, browser } = session;
            const referenceSessionItem = UI.createElement({
              style: "margin-right: 10px",
              className: "button is-dark is-small is-rounded is-outlined",
              onClick: () => WaveService.openSession(token),
              children: [
                {
                  element: "span",
                  className: "icon",
                  children: {
                    element: "i",
                    className: utils.getBrowserIcon(browser.name)
                  }
                },
                {
                  element: "span",
                  className: "is-family-monospace",
                  text: token.split("-").shift()
                }
              ]
            });
            referenceSessionsList.appendChild(referenceSessionItem);
          });
          referenceSessionsTarget.appendChild(referenceSessionsList);
        },
        renderApiResults() {
          const apiResultsView = UI.createElement({
            style: "margin-bottom: 20px"
          });

          const heading = UI.createElement({
            className: "title is-4",
            text: "Results"
          });
          apiResultsView.appendChild(heading);

          const { results, tokens, sessions } = comparisonUi.state;

          if (!results) {
            const loadingIndicator = UI.createElement({
              className: "level",
              children: {
                element: "span",
                className: "level-item icon",
                children: [
                  {
                    element: "i",
                    className: "fas fa-spinner fa-pulse"
                  },
                  {
                    style: "margin-left: 0.4em;",
                    text: "Loading comparison ..."
                  }
                ]
              }
            });
            apiResultsView.appendChild(loadingIndicator);

            const apiResults = UI.getElement("api-results");
            apiResults.innerHTML = "";
            apiResults.appendChild(apiResultsView);
            return;
          }

          const resultsTable = UI.createElement({
            element: "table"
          });
          apiResultsView.appendChild(resultsTable);

          const getColor = percent => {
            const tRed = 28;
            const tGreen = 166;
            const tBlue = 76;
            const mRed = 204;
            const mGreen = 163;
            const mBlue = 0;
            const bRed = 255;
            const bGreen = 56;
            const bBlue = 96;
            if (percent > 50) {
              const red = mRed + ((percent - 50) / 50) * (tRed - mRed);
              const green = mGreen + ((percent - 50) / 50) * (tGreen - mGreen);
              const blue = mBlue + ((percent - 50) / 50) * (tBlue - mBlue);
              return `rgb(${red}, ${green}, ${blue})`;
            } else {
              const red = bRed + (percent / 50) * (mRed - bRed);
              const green = bGreen + (percent / 50) * (mGreen - bGreen);
              const blue = bBlue + (percent / 50) * (mBlue - bBlue);
              return `rgb(${red}, ${green}, ${blue})`;
            }
          };

          const resultsTableHeader = UI.createElement({
            element: "thead",
            children: {
              element: "tr",
              children: [
                {
                  element: "td",
                  text: "API",
                  style: "vertical-align: bottom; width: 200px"
                }
              ]
                .concat(
                  tokens.map(token => ({
                    element: "td",
                    children: {
                      onClick: () => WaveService.openSession(token),
                      className: "session-header",
                      children: [
                        {
                          element: "i",
                          style: "font-size: 1.5em; margin-right: 0.1em",
                          className: utils.getBrowserIcon(
                            sessions[token].browser.name
                          )
                        },
                        {
                          children: [
                            {
                              style: "margin: 0; padding: 0;",
                              className: "is-family-monospace",
                              text: `${token.split("-").shift()}`
                            },
                            {
                              style: "margin: 0; padding: 0;",
                              text: `${sessions[token].browser.name} ${
                                sessions[token].browser.version
                              }`
                            }
                          ]
                        }
                      ]
                    }
                  }))
                )
                .concat([{ element: "td", style: "width: 80px" }])
            }
          });
          resultsTable.appendChild(resultsTableHeader);

          let apis = [];
          tokens.forEach(token =>
            Object.keys(results[token])
              .filter(api => apis.indexOf(api) === -1)
              .forEach(api => apis.push(api))
          );
          apis = apis.sort((apiA, apiB) =>
            apiA.toLowerCase() > apiB.toLowerCase() ? 1 : -1
          );

          const resultsTableBody = UI.createElement({
            element: "tbody",
            children: apis.map(api => ({
              element: "tr",
              children: [{ element: "td", text: api }]
                .concat(
                  tokens.map(token =>
                    results[token][api]
                      ? {
                          element: "td",
                          style:
                            "text-align: center; font-weight: bold;" +
                            `color: ${getColor(
                              utils.percent(
                                results[token][api],
                                results["total"][api]
                              )
                            )}`,
                          text: `${utils.percent(
                            results[token][api],
                            results["total"][api]
                          )}%`
                        }
                      : {
                          element: "td",
                          text: "Not Tested",
                          style: "text-align: center;"
                        }
                  )
                )
                .concat([
                  comparisonUi.state.reportsEnabled ?
                  {
                    element: "td",
                    children: {
                      className:
                        "html-report button is-dark is-outlined is-small",
                      onclick: () =>
                        WaveService.readMultiReportUri(
                          comparisonUi.state.tokens,
                          api,
                          function(uri) {
                            window.open(uri, "_blank");
                          }
                        ),
                      text: "report"
                    }
                  } : null
                ])
            }))
          });
          resultsTable.appendChild(resultsTableBody);

          const apiResults = UI.getElement("api-results");
          apiResults.innerHTML = "";
          apiResults.appendChild(apiResultsView);
        }
      };
    </script>
  </body>
</html>
