// Copyright (C) 2008 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.google.gerrit.client.account;

import com.google.gerrit.client.ErrorDialog;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.AccountScreen;
import com.google.gerrit.client.ui.SmallHeading;
import com.google.gerrit.client.ui.TextSaveButtonListener;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.AgreementInfo;
import com.google.gerrit.reviewdb.AccountAgreement;
import com.google.gerrit.reviewdb.AccountGroupAgreement;
import com.google.gerrit.reviewdb.ContributorAgreement;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwtexpui.globalkey.client.NpTextBox;
import com.google.gwtjsonrpc.client.VoidResult;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class NewAgreementScreen extends AccountScreen {
  private final String nextToken;
  private Set<ContributorAgreement.Id> mySigned;
  private List<ContributorAgreement> available;
  private ContributorAgreement current;

  private VerticalPanel radios;

  private Panel agreementGroup;
  private HTML agreementHtml;

  private Panel contactGroup;
  private ContactPanelFull contactPanel;

  private Panel finalGroup;
  private NpTextBox yesIAgreeBox;
  private Button submit;

  public NewAgreementScreen() {
    this(null);
  }

  public NewAgreementScreen(final String token) {
    nextToken = token != null ? token : PageLinks.SETTINGS_AGREEMENTS;
  }

  @Override
  protected void onLoad() {
    super.onLoad();
    Util.ACCOUNT_SVC.myAgreements(new GerritCallback<AgreementInfo>() {
      public void onSuccess(AgreementInfo result) {
        if (isAttached()) {
          mySigned = new HashSet<ContributorAgreement.Id>();
          for (AccountAgreement a : result.userAccepted) {
            mySigned.add(a.getAgreementId());
          }
          for (AccountGroupAgreement a : result.groupAccepted) {
            mySigned.add(a.getAgreementId());
          }
          postRPC();
        }
      }
    });
    Gerrit.SYSTEM_SVC
        .contributorAgreements(new GerritCallback<List<ContributorAgreement>>() {
          public void onSuccess(final List<ContributorAgreement> result) {
            if (isAttached()) {
              available = result;
              postRPC();
            }
          }
        });
  }

  @Override
  protected void onInitUI() {
    super.onInitUI();
    setPageTitle(Util.C.newAgreement());

    final FlowPanel formBody = new FlowPanel();
    radios = new VerticalPanel();
    formBody.add(radios);

    agreementGroup = new FlowPanel();
    agreementGroup
        .add(new SmallHeading(Util.C.newAgreementReviewLegalHeading()));

    agreementHtml = new HTML();
    agreementHtml.setStyleName(Gerrit.RESOURCES.css().contributorAgreementLegal());
    agreementGroup.add(agreementHtml);
    formBody.add(agreementGroup);

    contactGroup = new FlowPanel();
    contactGroup
        .add(new SmallHeading(Util.C.newAgreementReviewContactHeading()));
    formBody.add(contactGroup);

    finalGroup = new VerticalPanel();
    finalGroup.add(new SmallHeading(Util.C.newAgreementCompleteHeading()));
    final FlowPanel fp = new FlowPanel();
    yesIAgreeBox = new NpTextBox();
    yesIAgreeBox.setVisibleLength(Util.C.newAgreementIAGREE().length() + 8);
    yesIAgreeBox.setMaxLength(Util.C.newAgreementIAGREE().length());
    fp.add(yesIAgreeBox);
    fp.add(new InlineLabel(Util.M.enterIAGREE(Util.C.newAgreementIAGREE())));
    finalGroup.add(fp);
    submit = new Button(Util.C.buttonSubmitNewAgreement());
    submit.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(final ClickEvent event) {
        doSign();
      }
    });
    finalGroup.add(submit);
    formBody.add(finalGroup);
    new TextSaveButtonListener(yesIAgreeBox, submit);

    final FormPanel form = new FormPanel();
    form.add(formBody);
    add(form);
  }

  private void postRPC() {
    if (mySigned != null && available != null) {
      renderSelf();
      display();
    }
  }

  private void renderSelf() {
    current = null;
    agreementGroup.setVisible(false);
    contactGroup.setVisible(false);
    finalGroup.setVisible(false);
    radios.clear();

    final SmallHeading hdr = new SmallHeading();
    if (available.isEmpty()) {
      hdr.setText(Util.C.newAgreementNoneAvailable());
    } else {
      hdr.setText(Util.C.newAgreementSelectTypeHeading());
    }
    radios.add(hdr);

    for (final ContributorAgreement cla : available) {
      final RadioButton r = new RadioButton("cla_id", cla.getShortName());
      r.addStyleName(Gerrit.RESOURCES.css().contributorAgreementButton());
      radios.add(r);

      if (mySigned.contains(cla.getId())) {
        r.setEnabled(false);
        final Label l = new Label(Util.C.newAgreementAlreadySubmitted());
        l.setStyleName(Gerrit.RESOURCES.css().contributorAgreementAlreadySubmitted());
        radios.add(l);
      } else {
        r.addClickHandler(new ClickHandler() {
          @Override
          public void onClick(final ClickEvent event) {
            showCLA(cla);
          }
        });
      }

      if (cla.getShortDescription() != null
          && !cla.getShortDescription().equals("")) {
        final Label l = new Label(cla.getShortDescription());
        l.setStyleName(Gerrit.RESOURCES.css().contributorAgreementShortDescription());
        radios.add(l);
      }
    }
  }

  private void doSign() {
    submit.setEnabled(false);

    if (current == null
        || !Util.C.newAgreementIAGREE()
            .equalsIgnoreCase(yesIAgreeBox.getText())) {
      yesIAgreeBox.setText("");
      yesIAgreeBox.setFocus(true);
      return;
    }

    if (contactGroup.isVisible()) {
      contactPanel.doSave();
    }
    Util.ACCOUNT_SEC.enterAgreement(current.getId(),
        new GerritCallback<VoidResult>() {
          public void onSuccess(final VoidResult result) {
            Gerrit.display(nextToken);
          }

          @Override
          public void onFailure(final Throwable caught) {
            yesIAgreeBox.setText("");
            super.onFailure(caught);
          }
        });
  }

  private void showCLA(final ContributorAgreement cla) {
    current = cla;
    String url = cla.getAgreementUrl();
    if (url != null && url.length() > 0) {
      agreementGroup.setVisible(true);
      agreementHtml.setText(Gerrit.C.rpcStatusLoading());
      if (!url.startsWith("http:") && !url.startsWith("https:")) {
        url = GWT.getHostPageBaseURL() + url;
      }
      final RequestBuilder rb = new RequestBuilder(RequestBuilder.GET, url);
      rb.setCallback(new RequestCallback() {
        public void onError(Request request, Throwable exception) {
          new ErrorDialog(exception).center();
        }

        public void onResponseReceived(Request request, Response response) {
          final String ct = response.getHeader("Content-Type");
          if (response.getStatusCode() == 200 && ct != null
              && (ct.equals("text/html") || ct.startsWith("text/html;"))) {
            agreementHtml.setHTML(response.getText());
          } else {
            new ErrorDialog(response.getStatusText()).center();
          }
        }
      });
      try {
        rb.send();
      } catch (RequestException e) {
        new ErrorDialog(e).show();
      }
    } else {
      agreementGroup.setVisible(false);
    }

    if (contactPanel == null && cla.isRequireContactInformation()) {
      contactPanel = new ContactPanelFull();
      contactGroup.add(contactPanel);
      contactPanel.hideSaveButton();
    }
    contactGroup.setVisible(cla.isRequireContactInformation());
    finalGroup.setVisible(true);
    yesIAgreeBox.setText("");
    submit.setEnabled(false);
  }
}
