// Copyright (C) 2013 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.change;

import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.account.AccountApi;
import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.changes.ChangeInfo;
import com.google.gerrit.client.changes.ChangeInfo.FetchInfo;
import com.google.gerrit.client.changes.ChangeList;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.extensions.common.ListChangesOption;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadScheme;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
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.HorizontalPanel;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.clippy.client.CopyableLabel;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;

class DownloadBox extends VerticalPanel {
  private final static String ARCHIVE[] = {"tar", "tbz2", "tgz", "txz"};
  private final ChangeInfo change;
  private final String revision;
  private final PatchSet.Id psId;
  private final FlexTable commandTable;
  private final ListBox scheme;
  private NativeMap<FetchInfo> fetch;

  DownloadBox(ChangeInfo change, String revision, PatchSet.Id psId) {
    this.change = change;
    this.revision = revision;
    this.psId = psId;
    this.commandTable = new FlexTable();
    this.scheme = new ListBox();
    this.scheme.addChangeHandler(new ChangeHandler() {
      @Override
      public void onChange(ChangeEvent event) {
        renderCommands();
        if (Gerrit.isSignedIn()) {
          saveScheme();
        }
      }
    });

    setStyleName(Gerrit.RESOURCES.css().downloadBox());
    commandTable.setStyleName(Gerrit.RESOURCES.css().downloadBoxTable());
    scheme.setStyleName(Gerrit.RESOURCES.css().downloadBoxScheme());
    add(commandTable);
  }

  @Override
  protected void onLoad() {
    if (fetch == null) {
      RestApi call = ChangeApi.detail(change.legacy_id().get());
      ChangeList.addOptions(call, EnumSet.of(
          revision.equals(change.current_revision())
             ? ListChangesOption.CURRENT_REVISION
             : ListChangesOption.ALL_REVISIONS,
          ListChangesOption.DOWNLOAD_COMMANDS));
      call.get(new AsyncCallback<ChangeInfo>() {
        @Override
        public void onSuccess(ChangeInfo result) {
          fetch = result.revision(revision).fetch();
          renderScheme();
        }

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

  private void renderCommands() {
    commandTable.removeAllRows();

    if (scheme.getItemCount() > 0) {
      FetchInfo fetchInfo =
          fetch.get(scheme.getValue(scheme.getSelectedIndex()));
      for (String commandName : Natives.keys(fetchInfo.commands())) {
        CopyableLabel copyLabel =
            new CopyableLabel(fetchInfo.command(commandName));
        copyLabel.setStyleName(Gerrit.RESOURCES.css().downloadBoxCopyLabel());
        insertCommand(commandName, copyLabel);
      }
    }
    if (change.revision(revision).commit().parents().length() == 1) {
      insertPatch();
    }
    insertArchive();
    insertCommand(null, scheme);
  }

  private void insertPatch() {
    String id = revision.substring(0, 7);
    Anchor patchBase64 = new Anchor(id + ".diff.base64");
    patchBase64.setHref(new RestApi("/changes/")
      .id(psId.getParentKey().get())
      .view("revisions")
      .id(revision)
      .view("patch")
      .addParameterTrue("download")
      .url());

    Anchor patchZip = new Anchor(id + ".diff.zip");
    patchZip.setHref(new RestApi("/changes/")
      .id(psId.getParentKey().get())
      .view("revisions")
      .id(revision)
      .view("patch")
      .addParameterTrue("zip")
      .url());

    HorizontalPanel p = new HorizontalPanel();
    p.add(patchBase64);
    InlineLabel spacer = new InlineLabel("|");
    spacer.setStyleName(Gerrit.RESOURCES.css().downloadBoxSpacer());
    p.add(spacer);
    p.add(patchZip);
    insertCommand("Patch-File", p);
  }

  private void insertArchive() {
    List<Anchor> formats = new ArrayList<>(ARCHIVE.length);
    for (String f : ARCHIVE) {
      Anchor archive = new Anchor(f);
      archive.setHref(new RestApi("/changes/")
          .id(psId.getParentKey().get())
          .view("revisions")
          .id(revision)
          .view("archive")
          .addParameter("format", f)
          .url());
      formats.add(archive);
    }

    HorizontalPanel p = new HorizontalPanel();
    Iterator<Anchor> it = formats.iterator();
    while (it.hasNext()) {
      Anchor a = it.next();
      p.add(a);
      if (it.hasNext()) {
        InlineLabel spacer = new InlineLabel("|");
        spacer.setStyleName(Gerrit.RESOURCES.css().downloadBoxSpacer());
        p.add(spacer);
      }
    }
    insertCommand("Archive", p);
  }

  private void insertCommand(String commandName, Widget w) {
    int row = commandTable.getRowCount();
    commandTable.insertRow(row);
    commandTable.getCellFormatter().addStyleName(row, 0,
        Gerrit.RESOURCES.css().downloadBoxTableCommandColumn());
    if (commandName != null) {
      commandTable.setText(row, 0, commandName);
    }
    if (w != null) {
      commandTable.setWidget(row, 1, w);
    }
  }

  private void renderScheme() {
    for (String id : fetch.keySet()) {
      scheme.addItem(id);
    }
    if (scheme.getItemCount() == 0) {
      scheme.setVisible(false);
    } else {
      if (scheme.getItemCount() == 1) {
        scheme.setSelectedIndex(0);
        scheme.setVisible(false);
      } else {
        int select = 0;
        String find = getUserPreference();
        if (find != null) {
          for (int i = 0; i < scheme.getItemCount(); i++) {
            if (find.equals(scheme.getValue(i))) {
              select = i;
              break;
            }
          }
        }
        scheme.setSelectedIndex(select);
      }
    }
    renderCommands();
  }

  private static String getUserPreference() {
    if (Gerrit.isSignedIn()) {
      DownloadScheme pref =
          Gerrit.getUserAccount().getGeneralPreferences().getDownloadUrl();
      if (pref != null) {
        switch (pref) {
          case ANON_GIT:
            return "git";
          case ANON_HTTP:
            return "anonymous http";
          case HTTP:
            return "http";
          case SSH:
            return "ssh";
          case REPO_DOWNLOAD:
            return "repo";
          default:
            return null;
        }
      }
    }
    return null;
  }

  private void saveScheme() {
    DownloadScheme scheme = getSelectedScheme();
    AccountGeneralPreferences pref =
        Gerrit.getUserAccount().getGeneralPreferences();

    if (scheme != null && scheme != pref.getDownloadUrl()) {
      pref.setDownloadUrl(scheme);
      PreferenceInput in = PreferenceInput.create();
      in.download_scheme(scheme);
      AccountApi.self().view("preferences")
          .post(in, new AsyncCallback<JavaScriptObject>() {
            @Override
            public void onSuccess(JavaScriptObject result) {
            }

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

  private DownloadScheme getSelectedScheme() {
    String id = scheme.getValue(scheme.getSelectedIndex());
    if ("git".equals(id)) {
      return DownloadScheme.ANON_GIT;
    } else if ("anonymous http".equals(id)) {
      return DownloadScheme.ANON_HTTP;
    } else if ("http".equals(id)) {
      return DownloadScheme.HTTP;
    } else if ("ssh".equals(id)) {
      return DownloadScheme.SSH;
    } else if ("repo".equals(id)) {
      return DownloadScheme.REPO_DOWNLOAD;
    }
    return null;
  }

  private static class PreferenceInput extends JavaScriptObject {
    static PreferenceInput create() {
      return createObject().cast();
    }

    final void download_scheme(DownloadScheme s) {
      download_scheme0(s.name());
    }

    private final native void download_scheme0(String n) /*-{
      this.download_scheme = n;
    }-*/;

    protected PreferenceInput() {
    }
  }
}
