// Copyright (C) 2014 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.reviewers.client;

import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.plugin.client.rpc.RestApi;
import com.google.gerrit.plugin.client.screen.Screen;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwtexpui.globalkey.client.NpTextBox;

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

public class ReviewersScreen extends HorizontalPanel {
  private static final String REMOVE_BUTTON_IMG =
      "plugins/reviewers/static/remove_reviewer.png";
  static class Factory implements Screen.EntryPoint {
    @Override
    public void onLoad(Screen screen) {
      screen.setPageTitle("Reviewers");
      screen.show(
          new ReviewersScreen(URL.decodeQueryString(screen.getToken(1))));
    }
  }

  private boolean isOwner;
  private String projectName;
  private Set<ReviewerEntry> rEntries;

  ReviewersScreen(final String projectName) {
    setStyleName("reviewers-panel");
    this.projectName = projectName;
    this.rEntries = new HashSet<>();

    new RestApi("access/").addParameter("project", projectName).get(
        new AsyncCallback<NativeMap<ProjectAccessInfo>>() {

        @Override
        public void onSuccess(NativeMap<ProjectAccessInfo> result) {
          isOwner = result.get(projectName).isOwner();
          display();
        }

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

  void display() {
    new RestApi("projects").id(projectName).view("reviewers").get(
        new AsyncCallback<JsArray<ReviewerFilterSection>>() {

      @Override
      public void onSuccess(JsArray<ReviewerFilterSection> result) {
        display(result);
      }

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

  void display(JsArray<ReviewerFilterSection> sections) {
    add(createEntriesPanel(sections));
    add(createInputPanel());
  }

  Panel createEntriesPanel(JsArray<ReviewerFilterSection> sections) {
    Panel p = new VerticalPanel();
    for (ReviewerFilterSection section : Natives.asList(sections)) {
      Label filter = new Label(section.filter());
      filter.addStyleName("reviewers-filterLabel");
      p.add(filter);
      for (String reviewer : Natives.asList(section.reviewers())) {
        ReviewerEntry rEntry = new ReviewerEntry(section.filter(), reviewer);
        rEntries.add(rEntry);
        p.add(createOneEntry(rEntry));
      }
    }
    return p;
  }

  Panel createOneEntry(final ReviewerEntry e) {
    Label l = new Label(e.reviewer);
    l.setStyleName("reviewers-reviewerLabel");

    Image img = new Image(REMOVE_BUTTON_IMG);
    Button removeButton = Button.wrap(img.getElement());
    removeButton.setStyleName("reviewers-removeButton");
    removeButton.setTitle("remove reviewer");
    removeButton.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(final ClickEvent event) {
        doSave(Action.REMOVE, e);
      }
    });
    removeButton.setVisible(isOwner);

    HorizontalPanel p = new HorizontalPanel();
    p.add(l);
    p.add(removeButton);
    return p;
  }

  Panel createInputPanel(){
    Grid inputGrid = new Grid(2, 2);

    final NpTextBox filterBox = new NpTextBox();
    filterBox.getElement().setPropertyString("placeholder", "filter");
    inputGrid.setText(0, 0, "Filter: ");
    inputGrid.setWidget(0, 1, filterBox);

    // TODO(davido): Remove hard coded start suggest char 3
    final ReviewerSuggestOracle oracle = new ReviewerSuggestOracle(3, projectName);
    final SuggestBox reviewerBox = new SuggestBox(oracle, new NpTextBox());
    reviewerBox.getElement().setPropertyString("placeholder", "reviewer");
    inputGrid.setText(1, 0, "Reviewer: ");
    inputGrid.setWidget(1, 1, reviewerBox);

    Button addButton = new Button("Add");
    addButton.setStyleName("reviewers-addButton");
    addButton.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(final ClickEvent event) {
        ReviewerEntry e = new ReviewerEntry(filterBox.getValue(),
            reviewerBox.getValue());
        if (!rEntries.contains(e) && !e.filter.isEmpty() &&
            !e.reviewer.isEmpty()) {
          doSave(Action.ADD, e);
        }
        filterBox.setText("");
        reviewerBox.setText("");
      }
    });
    filterBox.setEnabled(isOwner);
    reviewerBox.setEnabled(isOwner);
    addButton.setEnabled(isOwner);

    Panel p = new VerticalPanel();
    p.setStyleName("reviewers-inputPanel");
    p.add(inputGrid);
    p.add(addButton);
    return p;
  }

  void doSave(Action action, ReviewerEntry entry) {
    ChangeReviewersInput in = ChangeReviewersInput.create();
    in.setAction(action);
    in.setFilter(entry.filter);
    in.setReviewer(entry.reviewer);
    reset();

    new RestApi("projects").id(projectName).view("reviewers").put(
        in, new AsyncCallback<JsArray<ReviewerFilterSection>>() {

      @Override
      public void onSuccess(JsArray<ReviewerFilterSection> result) {
        display(result);
      }

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

  void reset() {
    clear();
    rEntries = new HashSet<>();
  }

  static class ReviewerEntry {
    private String filter;
    private String reviewer;

    ReviewerEntry(String filter, String reviewer) {
      this.filter = filter;
      this.reviewer = reviewer;
    }

    @Override
    public int hashCode() {
      return Objects.hash(filter, reviewer);
    }

    @Override
    public boolean equals(Object o) {
      if (o == null || !(o instanceof ReviewerEntry)) {
        return false;
      }
      ReviewerEntry other = (ReviewerEntry) o;
      if (!this.filter.equals(other.filter)
          || !this.reviewer.equals(other.reviewer)) {
        return false;
      }
      return true;
    }
  }
}
