// 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.account;

import com.google.gerrit.client.VoidResult;
import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.info.GpgKeyInfo;
import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.NativeString;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.user.client.rpc.AsyncCallback;

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

/**
 * A collection of static methods which work on the Gerrit REST API for specific
 * accounts.
 */
public class AccountApi {
  public static RestApi self() {
    return new RestApi("/accounts/").view("self");
  }

  /** Retrieve the account edit preferences */
  public static void getEditPreferences(AsyncCallback<EditPreferences> cb) {
    self().view("preferences.edit").get(cb);
  }

  /** Put the account edit preferences */
  public static void putEditPreferences(EditPreferences in,
      AsyncCallback<EditPreferences> cb) {
    self().view("preferences.edit").put(in, cb);
  }

  public static void suggest(String query, int limit,
      AsyncCallback<JsArray<AccountInfo>> cb) {
    new RestApi("/accounts/")
      .addParameterTrue("suggest")
      .addParameter("q", query)
      .addParameter("n", limit)
      .background()
      .get(cb);
  }

  public static void putDiffPreferences(DiffPreferences in,
      AsyncCallback<DiffPreferences> cb) {
    self().view("preferences.diff").put(in, cb);
  }

  /** Retrieve the username */
  public static void getUsername(String account, AsyncCallback<NativeString> cb) {
    new RestApi("/accounts/").id(account).view("username").get(cb);
  }

  /** Set the username */
  public static void setUsername(String account, String username,
      AsyncCallback<NativeString> cb) {
    UsernameInput input = UsernameInput.create();
    input.username(username);
    new RestApi("/accounts/").id(account).view("username").put(input, cb);
  }

  /** Retrieve the account name */
  public static void getName(String account, AsyncCallback<NativeString> cb) {
    new RestApi("/accounts/").id(account).view("name").get(cb);
  }

  /** Retrieve email addresses */
  public static void getEmails(String account,
      AsyncCallback<JsArray<EmailInfo>> cb) {
    new RestApi("/accounts/").id(account).view("emails").get(cb);
  }

  /** Register a new email address */
  public static void registerEmail(String account, String email,
      AsyncCallback<EmailInfo> cb) {
    JavaScriptObject in = JavaScriptObject.createObject();
    new RestApi("/accounts/").id(account).view("emails").id(email)
        .ifNoneMatch().put(in, cb);
  }

  /** Retrieve SSH keys */
  public static void getSshKeys(String account,
      AsyncCallback<JsArray<SshKeyInfo>> cb) {
    new RestApi("/accounts/").id(account).view("sshkeys").get(cb);
  }

  /** Add a new SSH keys */
  public static void addSshKey(String account, String sshPublicKey,
      AsyncCallback<SshKeyInfo> cb) {
    new RestApi("/accounts/").id(account).view("sshkeys")
        .post(sshPublicKey, cb);
  }

  /** Retrieve Watched Projects */
  public static void getWatchedProjects(String account,
      AsyncCallback<JsArray<ProjectWatchInfo>> cb) {
    new RestApi("/accounts/").id(account).view("watched.projects").get(cb);
  }

  /** Create/Update Watched Project */
  public static void updateWatchedProject(
      String account,
      ProjectWatchInfo watchedProjectInfo,
      AsyncCallback<JsArray<ProjectWatchInfo>> cb) {
    Set<ProjectWatchInfo> watchedProjectInfos = new HashSet<>();
    watchedProjectInfos.add(watchedProjectInfo);
    updateWatchedProjects(account, watchedProjectInfos, cb);
  }

  /** Create/Update Watched Projects */
  public static void updateWatchedProjects(
      String account,
      Set<ProjectWatchInfo> watchedProjectInfos,
      AsyncCallback<JsArray<ProjectWatchInfo>> cb) {
    new RestApi("/accounts/")
        .id(account)
        .view("watched.projects")
        .post(projectWatchArrayFromSet(watchedProjectInfos), cb);
  }

  /** Delete Watched Project */
  public static void deleteWatchedProject(
      String account,
      ProjectWatchInfo watchedProjectInfo,
      AsyncCallback<JsArray<ProjectWatchInfo>> cb) {
    Set<ProjectWatchInfo> watchedProjectInfos = new HashSet<>();
    watchedProjectInfos.add(watchedProjectInfo);
    deleteWatchedProjects(account, watchedProjectInfos, cb);
  }

  /** Delete Watched Projects */
  public static void deleteWatchedProjects(
      String account,
      Set<ProjectWatchInfo> watchedProjectInfos,
      AsyncCallback<JsArray<ProjectWatchInfo>> cb) {
    new RestApi("/accounts/")
        .id(account)
        .view("watched.projects:delete")
        .post(projectWatchArrayFromSet(watchedProjectInfos), cb);
  }

  /**
   * Delete SSH keys. For each key to be deleted a separate DELETE request is
   * fired to the server. The {@code onSuccess} method of the provided callback
   * is invoked once after all requests succeeded. If any request fails the
   * callbacks' {@code onFailure} method is invoked. In a failure case it can be
   * that still some of the keys were successfully deleted.
   */
  public static void deleteSshKeys(String account,
      Set<Integer> sequenceNumbers, AsyncCallback<VoidResult> cb) {
    CallbackGroup group = new CallbackGroup();
    for (int seq : sequenceNumbers) {
      new RestApi("/accounts/").id(account).view("sshkeys").id(seq)
          .delete(group.add(cb));
      cb = CallbackGroup.emptyCallback();
    }
    group.done();
  }

  /** Retrieve the HTTP password */
  public static void getHttpPassword(String account,
      AsyncCallback<NativeString> cb) {
    new RestApi("/accounts/").id(account).view("password.http").get(cb);
  }

  /** Generate a new HTTP password */
  public static void generateHttpPassword(String account,
      AsyncCallback<NativeString> cb) {
    HttpPasswordInput in = HttpPasswordInput.create();
    in.generate(true);
    new RestApi("/accounts/").id(account).view("password.http").put(in, cb);
  }

  /** Clear HTTP password */
  public static void clearHttpPassword(String account,
      AsyncCallback<VoidResult> cb) {
    new RestApi("/accounts/").id(account).view("password.http").delete(cb);
  }

  private static JsArray<ProjectWatchInfo> projectWatchArrayFromSet(
      Set<ProjectWatchInfo> set) {
    JsArray<ProjectWatchInfo> jsArray = JsArray.createArray().cast();
    for (ProjectWatchInfo p : set) {
      jsArray.push(p);
    }
    return jsArray;
  }

  private static class HttpPasswordInput extends JavaScriptObject {
    final native void generate(boolean g) /*-{ if(g)this.generate=g; }-*/;

    static HttpPasswordInput create() {
      return createObject().cast();
    }

    protected HttpPasswordInput() {
    }
  }

  private static class UsernameInput extends JavaScriptObject {
    final native void username(String u) /*-{ if(u)this.username=u; }-*/;

    static UsernameInput create() {
      return createObject().cast();
    }

    protected UsernameInput() {
    }
  }

  public static void addGpgKey(String account, String armored,
      AsyncCallback<NativeMap<GpgKeyInfo>> cb) {
    new RestApi("/accounts/")
      .id(account)
      .view("gpgkeys")
      .post(GpgKeysInput.add(armored), cb);
  }

  public static void deleteGpgKeys(String account,
      Iterable<String> fingerprints, AsyncCallback<NativeMap<GpgKeyInfo>> cb) {
    new RestApi("/accounts/")
      .id(account)
      .view("gpgkeys")
      .post(GpgKeysInput.delete(fingerprints), cb);
  }

  private static class GpgKeysInput extends JavaScriptObject {
    static GpgKeysInput add(String key) {
      return createWithAdd(Natives.arrayOf(key));
    }

    static GpgKeysInput delete(Iterable<String> fingerprints) {
      return createWithDelete(Natives.arrayOf(fingerprints));
    }

    private static native GpgKeysInput createWithAdd(JsArrayString keys) /*-{
      return {'add': keys};
    }-*/;

    private static native GpgKeysInput createWithDelete(
        JsArrayString fingerprints) /*-{
      return {'delete': fingerprints};
    }-*/;

    protected GpgKeysInput() {
    }
  }
}
