/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.benchmarks.viewer.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.HistoryListener;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CellPanel;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SourcesTableEvents;
import com.google.gwt.user.client.ui.TableListener;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

/**
 * The application for viewing benchmark reports. In order for the ReportViewer
 * to operate correctly, you must have both the {@link ReportServer} RPC and
 * {@link com.google.gwt.junit.viewer.server.ReportImageServer} servlets up and
 * running within a servlet container.
 * 
 * <code>ReportViewer's</code> GWT XML module is configured to start these
 * servlets by default. Just start <code>ReportViewer</code> in hosted mode,
 * and GWT will run them within its own embedded servlet engine. For example,
 * 
 * <pre>java -cp &lt;classpath&gt; com.google.gwt.dev.GWTShell -out
 * ReportViewerShell/www
 * com.google.gwt.junit.viewer.ReportViewer/ReportViewer.html</pre>
 * 
 * You can configure the location where ReportServer reads the benchmark reports
 * from by setting the system property named in
 * {@link com.google.gwt.benchmarks.client.Benchmark#REPORT_PATH}.
 */
@SuppressWarnings("deprecation")
public class ReportViewer implements EntryPoint, HistoryListener {

  private static class MutableBool {

    boolean value;

    MutableBool(boolean value) {
      this.value = value;
    }
  }

  private class SummariesTableListener implements TableListener {

    public void onCellClicked(SourcesTableEvents sender, int row, int col) {
      if (row > 0) {
        ReportSummary summary = summaries.get(row - 1);
        String token = summary.getId();
        // Short circuit the history loop.
        selectReport(row, token);
        History.newItem(token);
      }
    }
  }

  private static final String imageServer = GWT.getModuleBaseURL()
      + "test_images/";

  HTML detailsLabel;

  Report report;

  VerticalPanel reportPanel;

  ReportServerAsync reportServer;

  FlexTable reportTable;

  HTML statusLabel;

  List<ReportSummary> summaries;

  VerticalPanel summariesPanel;

  FlexTable summariesTable;

  CellPanel topPanel;

  private int currentSelectedRow;

  private String currentToken;

  public void onHistoryChanged(String token) {
    assert (summaries != null);
    int row = 1;
    for (ReportSummary summary : summaries) {
      if (summary.getId().equals(token)) {
        selectReport(row, token);
        return;
      }
      ++row;
    }
    selectReport(0, token);
  }

  public void onModuleLoad() {
    init();

    // Asynchronously load the summaries
    reportServer = (ReportServerAsync) GWT.create(ReportServer.class);

    reportServer.getReportSummaries(new AsyncCallback<List<ReportSummary>>() {
      public void onFailure(Throwable caught) {
        String msg = "<p>" + caught.toString() + "</p>"
            + "<p>Is your path to the reports correct?</p>";
        statusLabel.setHTML(msg);
      }

      public void onSuccess(List<ReportSummary> result) {
        summaries = result;
        if (summaries != null) {
          if (summaries.size() == 0) {
            statusLabel.setText("There are no benchmark reports available in this folder.");
          }
          Collections.sort(summaries, new Comparator<ReportSummary>() {
            public int compare(ReportSummary r1, ReportSummary r2) {
              return r2.getDate().compareTo(r1.getDate()); // most recent first
            }
          });
          displaySummaries();

          // If there's an initial URL, browse to it.
          onHistoryChanged(History.getToken());
          History.addHistoryListener(ReportViewer.this);
        }
      }
    });
  }

  protected void selectReport(int row, String token) {
    if (row == currentSelectedRow && token.equals(currentToken)) {
      return;
    }
    if (currentSelectedRow != -1) {
      summariesTable.getRowFormatter().removeStyleName(currentSelectedRow,
          "viewer-SelectedRow");
    }
    currentToken = token;
    currentSelectedRow = row;

    if (row < 1) {
      clearReport();
    } else {
      fetchReport(row, token);
    }
  }

  private void clearReport() {
    statusLabel.setText("Select a report.");
    detailsLabel.setHTML("<h3>Report Details</h3>");
    reportPanel.remove(reportTable);
  }

  private FlexTable createReportTable() {
    FlexTable topTable = new FlexTable();

    FlexTable tempReportTable = new FlexTable();
    tempReportTable.setBorderWidth(1);
    tempReportTable.setCellPadding(5);
    tempReportTable.setWidget(0, 0, new Label("Date Created"));
    tempReportTable.setWidget(0, 1, new Label("GWT Version"));

    if (report == null) {
      tempReportTable.setWidget(1, 0,
          new Label("No currently selected report."));
      tempReportTable.getFlexCellFormatter().setColSpan(1, 0, 3);
      return tempReportTable;
    }

    detailsLabel.setHTML("<h3>" + report.getId() + " details </h3>");
    tempReportTable.setWidget(1, 0, new Label(report.getDateString()));
    tempReportTable.setWidget(1, 1, new Label(report.getGwtVersion()));

    // topTable.setWidget( 0, 0, tempReportTable );
    int currentRow = 1;

    Collections.sort(report.getCategories(), new Comparator<Category>() {
      public int compare(Category c1, Category c2) {
        return c1.getName().compareTo(c2.getName());
      }
    }); // Should be done once in the RPC

    for (int i = 0; i < report.getCategories().size(); ++i) {
      Category c = report.getCategories().get(i);

      if (!c.getName().equals("")) {
        FlexTable categoryTable = new FlexTable();
        categoryTable.setBorderWidth(0);
        categoryTable.setCellPadding(5);
        categoryTable.setText(0, 0, c.getName());
        categoryTable.getFlexCellFormatter().setStyleName(0, 0,
            "benchmark-category");

        categoryTable.setWidget(0, 1, new Label("Description"));
        categoryTable.setWidget(1, 0, new Label(c.getName()));
        categoryTable.setWidget(1, 1, new Label(c.getDescription()));

        topTable.setWidget(currentRow++, 0, categoryTable);
      }

      Collections.sort(c.getBenchmarks(), new Comparator<Benchmark>() {
        public int compare(Benchmark b1, Benchmark b2) {
          return b1.getName().compareTo(b2.getName());
        }
      }); // Should be done once in the RPC

      for (int j = 0; j < c.getBenchmarks().size(); ++j) {
        Benchmark benchmark = c.getBenchmarks().get(j);

        FlexTable benchmarkTable = new FlexTable();
        benchmarkTable.setBorderWidth(0);
        benchmarkTable.setCellPadding(5);
        benchmarkTable.setText(0, 0, benchmark.getName());
        // benchmarkTable.setText(0, 1, benchmark.getDescription());
        String codeHtml;
        String sourceText = benchmark.getSourceCode();
        if (sourceText != null) {
          Element tempElem = DOM.createDiv();
          DOM.setInnerText(tempElem, sourceText);
          String escapedCodeHtml = DOM.getInnerHTML(tempElem);
          codeHtml = "<pre>" + escapedCodeHtml + "</pre>";
        } else {
          codeHtml = "<i>(source not available)</i>";
        }
        benchmarkTable.setWidget(1, 0, new HTML(codeHtml));
        benchmarkTable.getFlexCellFormatter().setStyleName(0, 0,
            "benchmark-name");
        // benchmarkTable.getFlexCellFormatter().setStyleName( 0, 1,
        // "benchmark-description" );
        benchmarkTable.getFlexCellFormatter().setStyleName(1, 0,
            "benchmark-code");

        // TODO(tobyr) Provide detailed benchmark information.
        // Following bits of commented code are steps in that direction.
        /*
         * benchmarkTable.setWidget( 0, 1, new Label( "Description"));
         * benchmarkTable.setWidget( 0, 2, new Label( "Class Name"));
         * benchmarkTable.setWidget( 0, 3, new Label( "Source Code"));
         * benchmarkTable.setWidget( 1, 0, new Label( benchmark.getName()));
         * benchmarkTable.setWidget( 1, 1, new Label(
         * benchmark.getDescription())); benchmarkTable.setWidget( 1, 2, new
         * Label( benchmark.getClassName())); benchmarkTable.setWidget( 1, 3,
         * new HTML( "<pre>" + benchmark.getSourceCode() + "</pre>"));
         */
        topTable.setWidget(currentRow++, 0, benchmarkTable);

        FlexTable resultsTable = new FlexTable();
        resultsTable.setBorderWidth(0);
        resultsTable.setCellPadding(5);
        FlexTable.FlexCellFormatter resultsFormatter = resultsTable.getFlexCellFormatter();
        topTable.setWidget(currentRow++, 0, resultsTable);

        Collections.sort(benchmark.getResults(), new Comparator<Result>() {
          public int compare(Result r1, Result r2) {
            return r1.getAgent().compareTo(r2.getAgent());
          }
        }); // Should be done once in the RPC

        final List<FlexTable> trialsTables = new ArrayList<FlexTable>();

        int numVariables = 0;
        List<String> variableNames = null;
        if (benchmark.getResults().size() > 0) {
          Result sampleResult = benchmark.getResults().get(0);
          if (sampleResult.getTrials().size() > 0) {
            Trial sampleTrial = sampleResult.getTrials().get(0);
            numVariables = sampleTrial.getVariables().size();
            Map<String, String> variables = sampleTrial.getVariables();
            variableNames = new ArrayList<String>(variables.keySet());
            Collections.sort(variableNames);
          }
        }
        final MutableBool isVisible = new MutableBool(numVariables > 2);
        String buttonName = isVisible.value ? "Hide Data" : "Show Data";

        Button visibilityButton = new Button(buttonName, new ClickListener() {
          public void onClick(Widget sender) {
            isVisible.value = !isVisible.value;
            for (int i = 0; i < trialsTables.size(); ++i) {
              Widget w = trialsTables.get(i);
              w.setVisible(isVisible.value);
            }
            String name = isVisible.value ? "Hide Data" : "Show Data";
            ((Button) sender).setText(name);
          }
        });

        for (int k = 0; k < benchmark.getResults().size(); ++k) {
          Result result = benchmark.getResults().get(k);

          // Currently only support graphs for results of 2 variables or less
          if (numVariables <= 2) {
            resultsTable.setWidget(0, k, new Image(getImageUrl(report.getId(),
                c.getName(), benchmark.getClassName(), benchmark.getName(),
                result.getAgent())));
          } else {
            if (k == 0) {
              resultsTable.setHTML(0, k, "<b>"
                  + BrowserInfo.getBrowser(result.getAgent())
                  + "</b><br><font size=\"-1\">(Graphs are not yet available "
                  + "for benchmarks with more than two parameters)</font>");
            }
          }

          /*
           * FlexTable allTrialsTable = new FlexTable();
           * allTrialsTable.setBorderWidth(1); allTrialsTable.setCellPadding(5);
           * FlexTable.CellFormatter allTrialsFormatter = allTrialsTable
           * .getFlexCellFormatter(); topTable.setWidget(currentRow++, 0,
           * allTrialsTable); allTrialsTable.setWidget(0, k, trialsTable);
           * allTrialsFormatter .setAlignment(0, k,
           * HasHorizontalAlignment.ALIGN_CENTER,
           * HasVerticalAlignment.ALIGN_TOP);
           */

          resultsFormatter.setAlignment(2, k,
              HasHorizontalAlignment.ALIGN_LEFT, HasVerticalAlignment.ALIGN_TOP);

          // A table of straight data for all trials for an agent
          FlexTable trialsTable = new FlexTable();
          trialsTable.setVisible(isVisible.value);
          trialsTables.add(trialsTable);
          trialsTable.setBorderWidth(1);
          trialsTable.setCellPadding(5);

          if (k == 0) {
            resultsTable.setWidget(1, k, visibilityButton);
            resultsFormatter.setColSpan(1, k, benchmark.getResults().size());
            resultsFormatter.setAlignment(1, k,
                HasHorizontalAlignment.ALIGN_LEFT,
                HasVerticalAlignment.ALIGN_MIDDLE);
          }

          resultsTable.setWidget(2, k, trialsTable);

          // Write out the variable column headers
          for (int varIndex = 0; varIndex < numVariables; ++varIndex) {
            String varName = variableNames.get(varIndex);
            trialsTable.setHTML(0, varIndex, varName);
          }

          // Timing header
          trialsTable.setHTML(0, numVariables, "Timing (ms)");

          // Write out all the trial data
          int l = 0;
          for (Trial trial : result.getTrials()) {
            // Write the variable values
            for (int varIndex = 0; varIndex < numVariables; ++varIndex) {
              String varName = variableNames.get(varIndex);
              String varValue = trial.getVariables().get(varName);
              trialsTable.setHTML(l + 1, varIndex, varValue);
            }

            // Write out the timing data
            String data = trial.getRunTimeMillis() + "";
            trialsTable.setHTML(l + 1, numVariables, data);
            ++l;
          }

          if (result.getException() != null) {
            trialsTable.setHTML(l + 1, numVariables, result.getException());
          }
        }
      }
    }

    return topTable;
  }

  private FlexTable createSummariesTable() {
    FlexTable tempSummariesTable = new FlexTable();
    tempSummariesTable.addStyleName("viewer-List");
    tempSummariesTable.setCellPadding(5);
    tempSummariesTable.setBorderWidth(1);
    tempSummariesTable.setCellSpacing(0);
    tempSummariesTable.setWidget(0, 0, new Label("Report"));
    tempSummariesTable.setWidget(0, 1, new Label("Date Created"));
    tempSummariesTable.setWidget(0, 2, new Label("Tests"));
    tempSummariesTable.getRowFormatter().addStyleName(0, "viewer-ListHeader");

    if (summaries == null) {
      tempSummariesTable.setWidget(1, 0, new Label("Fetching reports..."));
      tempSummariesTable.getFlexCellFormatter().setColSpan(1, 0, 4);
      return tempSummariesTable;
    }

    for (int i = 0; i < summaries.size(); ++i) {
      ReportSummary summary = summaries.get(i);
      int index = i + 1;
      tempSummariesTable.setWidget(index, 0, new Hyperlink(summary.getId(),
          summary.getId()));
      tempSummariesTable.setWidget(index, 1, new Label(summary.getDateString()));
      tempSummariesTable.setWidget(index, 2, new Label(
          String.valueOf(summary.getNumTests())));
    }

    tempSummariesTable.addTableListener(new SummariesTableListener());
    return tempSummariesTable;
  }

  private void displayReport() {
    FlexTable table = createReportTable();
    reportPanel.remove(reportTable);
    reportTable = table;
    reportPanel.insert(reportTable, 1);
  }

  private void displaySummaries() {
    FlexTable table = createSummariesTable();
    summariesPanel.remove(summariesTable);
    summariesTable = table;
    summariesPanel.insert(summariesTable, 1);
  }

  private String encode(String str) {
    if (str.equals("")) {
      return str;
    }
    return URL.encodeComponent(str);
  }

  private void fetchReport(int row, String token) {
    summariesTable.getRowFormatter().addStyleName(row, "viewer-SelectedRow");
    statusLabel.setText("Retrieving the report...");
    reportServer.getReport(token, new AsyncCallback<Report>() {
      public void onFailure(Throwable caught) {
        statusLabel.setText(caught.toString());
      }

      public void onSuccess(Report result) {
        report = result;
        statusLabel.setText("Finished fetching report details.");
        displayReport();
      }
    });
  }

  private String getImageUrl(String report, String category, String testClass,
      String testMethod, String agent) {
    return imageServer + encode(report) + "/" + encode(category) + "/"
        + encode(testClass) + "/" + encode(testMethod) + "/" + encode(agent);
  }

  private void init() {
    topPanel = new VerticalPanel();

    summariesPanel = new VerticalPanel();
    summariesPanel.add(new HTML("<h3>Benchmark Reports</h3>"));
    summariesTable = createSummariesTable();
    summariesPanel.add(summariesTable);

    reportPanel = new VerticalPanel();
    detailsLabel = new HTML();
    reportPanel.add(detailsLabel);
    reportTable = createReportTable();
    // reportPanel.add( reportTable );

    topPanel.add(summariesPanel);
    CellPanel spacerPanel = new HorizontalPanel();
    spacerPanel.setSpacing(10);
    spacerPanel.add(new Label());
    topPanel.add(spacerPanel);
    topPanel.add(reportPanel);
    final RootPanel root = RootPanel.get();

    root.add(topPanel);

    statusLabel = new HTML();
    root.add(statusLabel);

    selectReport(0, "");
  }
}
