// 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.addCheckBox;
import static com.googlesource.gerrit.plugins.importer.client.InputUtil.addPasswordTextBox;
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() {
                  @Override
                  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);
  }
}
