// Copyright (C) 2015 The Android Open Source Project
//
// 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.googlesource.gerrit.plugins.importer.client;

import static com.googlesource.gerrit.plugins.importer.client.ImportProjectListScreen.projectUrl;
import static com.googlesource.gerrit.plugins.importer.client.ImportProjectListScreen.removeNs;

import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.plugin.client.Plugin;
import com.google.gerrit.plugin.client.rpc.RestApi;
import com.google.gerrit.plugin.client.screen.Screen;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.InlineHyperlink;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import java.util.Collections;
import java.util.List;

public class ProjectImportsScreen extends VerticalPanel {
  static class Factory implements Screen.EntryPoint {
    @Override
    public void onLoad(Screen screen) {
      screen.setPageTitle("Imports of  " + screen.getToken(1));
      screen.show(new ProjectImportsScreen(screen.getToken(1)));
    }
  }

  ProjectImportsScreen(final String project) {
    setStyleName("importer-import-panel");

    new RestApi("config")
        .id("server")
        .view(Plugin.get().getPluginName(), "projects")
        .id(project)
        .get(
            new AsyncCallback<ImportProjectInfo>() {
              @Override
              public void onSuccess(ImportProjectInfo importProjectInfo) {
                display(project, importProjectInfo);
              }

              @Override
              public void onFailure(Throwable caught) {
                // never invoked
              }
            });
  }

  private void display(final String project, ImportProjectInfo info) {
    MyTable t = new MyTable();
    t.setStyleName("importer-projectImportInfoTable");
    t.addRow("Project Name", project);
    t.addRow("Type", info.from() != null ? "IMPORT" : "COPY");

    if (info.from() != null) {
      String srcProjectUrl = projectUrl(info, project);
      t.addRow("From", new Anchor(srcProjectUrl, srcProjectUrl));
    } else {
      t.addRow("From", new InlineHyperlink(project, "/admin/projects/" + project));
    }

    t.addRow("Parent", info.parent());
    t.addRow("Actions", new ImportActionPanel(project, info.from() == null));
    add(t);

    add(new Label("Imports:"));
    int columns = 3;
    FlexTable importsTable = new FlexTable();
    importsTable.setStyleName("importer-importProjectTable");
    FlexCellFormatter fmt = importsTable.getFlexCellFormatter();
    for (int c = 0; c < columns; c++) {
      fmt.addStyleName(0, c, "dataHeader");
      fmt.addStyleName(0, c, "topMostCell");
    }
    fmt.addStyleName(0, 0, "leftMostCell");

    importsTable.setText(0, 0, "Timestamp");
    importsTable.setText(0, 1, "User");
    importsTable.setText(0, 2, "Remote User");
    int row = 1;
    List<ImportInfo> imports = Natives.asList(info.imports());
    Collections.reverse(imports);
    for (ImportInfo importInfo : imports) {
      for (int c = 0; c < columns; c++) {
        fmt.addStyleName(row, c, "dataCell");
        fmt.addStyleName(row, 0, "leftMostCell");
      }

      importsTable.setText(row, 0, removeNs(importInfo.timestamp()));
      importsTable.setText(row, 1, importInfo.user().username());
      importsTable.setText(row, 2, importInfo.remoteUser());

      row++;
    }

    add(importsTable);
  }

  private static class MyTable extends FlexTable {
    private static int row = 0;

    private void addRow(String label, String value) {
      setWidget(row, 0, new Label(label + ":"));
      setWidget(row, 1, new Label(value));
      row++;
    }

    private void addRow(String label, Widget w) {
      setWidget(row, 0, new Label(label + ":"));
      setWidget(row, 1, w);
      row++;
    }
  }
}
