// 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.InputUtil.addPasswordTextBox;
import static com.googlesource.gerrit.plugins.importer.client.InputUtil.addCheckBox;
import static com.googlesource.gerrit.plugins.importer.client.InputUtil.addTextBox;
import static com.googlesource.gerrit.plugins.importer.client.InputUtil.getValue;

import com.google.gerrit.plugin.client.Plugin;
import com.google.gerrit.plugin.client.rpc.RestApi;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwtexpui.globalkey.client.GlobalKey;
import com.google.gwtexpui.user.client.AutoCenterDialogBox;

public class ResumeImportDialog extends AutoCenterDialogBox {

  private final Button cancelButton;
  private final Button resumeButton;
  private TextBox userTxt;
  private TextBox passTxt;
  private final CheckBox forceCheckBox;

  public ResumeImportDialog(final String project, final boolean copy) {
    super(/* auto hide */false, /* modal */true);
    setGlassEnabled(true);
    setText("Resume Project " + (copy ? "Copy" : "Import"));

    FlowPanel buttons = new FlowPanel();

    resumeButton = new Button();
    resumeButton.setText("Resume");
    resumeButton.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        hide();

        RestApi restApi;
        ResumeImportProjectInput in = ResumeImportProjectInput.create();
        in.force(forceCheckBox.getValue());
        if (copy) {
          restApi = new RestApi("projects").id(project)
              .view(Plugin.get().getName(), "copy.resume");
        } else {
          restApi = new RestApi("config").id("server")
              .view(Plugin.get().getName(), "projects").id(project)
              .view("resume");
          in.user(getValue(userTxt));
          in.pass(getValue(passTxt));
        }

        restApi.put(in, new AsyncCallback<ResumeImportStatisticInfo>() {
              @Override
              public void onSuccess(ResumeImportStatisticInfo result) {
                Plugin.get().go("/x/" + Plugin.get().getName() + "/list");

                final DialogBox successDialog = new DialogBox();
                successDialog.setText("Resume " + (copy ? "Copy" : "Import") + " Import");
                successDialog.setAnimationEnabled(true);

                Panel p = new VerticalPanel();
                p.setStyleName("importer-message-panel");
                p.add(new Label("The project " + (copy ? "copy" : "import") + " was resumed."));
                p.add(new Label("Created Changes: " + result.numChangesCreated()));
                p.add(new Label("Updated Changes: " + result.numChangesUpdated()));
                Button okButton = new Button("OK");
                okButton.addClickHandler(new ClickHandler() {
                  public void onClick(ClickEvent event) {
                    successDialog.hide();
                  }
                });

                p.add(okButton);
                successDialog.add(p);

                successDialog.center();
                successDialog.show();
              }

              @Override
              public void onFailure(Throwable caught) {
              }
            });
      }
    });
    buttons.add(resumeButton);

    cancelButton = new Button();
    cancelButton.addStyleName("importer-cancel-button");
    cancelButton.setText("Cancel");
    cancelButton.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        hide();
      }
    });
    buttons.add(cancelButton);

    FlowPanel center = new FlowPanel();
    Label msg = new Label("Resume " + (copy ? "copy" : "import")
        + " of project '" + project + "'");
    msg.addStyleName("importer-resume-message");
    center.add(msg);

    if (!copy) {
      userTxt = addTextBox(center, "Remote User*", "user on remote system");
      passTxt = addPasswordTextBox(center, "Password*", "password of remote user");
    }
    forceCheckBox = addCheckBox(center, "Force", "whether resume should be done forcefully");

    center.add(buttons);
    add(center);

    setWidget(center);
  }

  @Override
  public void center() {
    super.center();
    GlobalKey.dialog(this);
    cancelButton.setFocus(true);
  }
}
