/*
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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.gcloud.spi;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.api.services.cloudresourcemanager.model.Policy;
import com.google.api.services.cloudresourcemanager.model.Project;
import com.google.common.collect.ImmutableList;
import com.google.gcloud.resourcemanager.ResourceManagerException;

import java.util.Collections;
import java.util.List;

public interface ResourceManagerRpc {

  public enum Permission {
    CREATE,
    DELETE,
    GET,
    LIST,
    UPDATE,
    GET_IAM_POLICY,
    SET_IAM_POLICY
  }

  class Tuple<X, Y> {
    private final X x;
    private final Y y;

    private Tuple(X x, Y y) {
      this.x = x;
      this.y = y;
    }

    public static <X, Y> Tuple<X, Y> of(X x, Y y) {
      return new Tuple<>(x, y);
    }

    public X x() {
      return x;
    }

    public Y y() {
      return y;
    }
  }

  public class ListOptions {
    private List<String> filters;
    private String pageToken;
    private int pageSize;

    private static final ListOptions DEFAULT_INSTANCE =
        new ListOptions(Collections.<String>emptyList(), null, -1);

    ListOptions(List<String> filters, String pageToken, int pageSize) {
      this.filters = checkNotNull(ImmutableList.copyOf(filters));
      this.pageToken = pageToken;
      this.pageSize = pageSize;
    }

    public static ListOptions getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    public static ListOptions createListOption(
        List<String> filters, String pageToken, int pageSize) {
      return new ListOptions(filters, pageToken, pageSize);
    }

    public String pageToken() {
      return pageToken;
    }

    public List<String> filters() {
      return filters;
    }

    public int pageSize() {
      return pageSize;
    }
  }

  Project create(Project project) throws ResourceManagerException;

  void delete(String projectId) throws ResourceManagerException;

  Project get(String projectId) throws ResourceManagerException;

  Tuple<String, Iterable<Project>> list(ListOptions listOptions) throws ResourceManagerException;

  void undelete(String projectId) throws ResourceManagerException;

  Project update(Project project) throws ResourceManagerException;

  Policy getIamPolicy(String projectId) throws ResourceManagerException;

  void setIamPolicy(String projectId, Policy policy) throws ResourceManagerException;

  List<Boolean> hasPermissions(String projectId, List<Permission> permissions)
      throws ResourceManagerException;

  // TODO(ajaykannan): implement "Organization" functionality when available
}

@@ -1178,16 +1178,237 @@
 CY%0A  %7D%0A%0A
+  public enum DeleteResult %7B%0A    SUCCESS,%0A    ALREADY_DELETED%0A  %7D%0A%0A  public enum UndeleteResult %7B%0A    SUCCESS,%0A    DELETE_IN_PROGRESS,%0A    GONE%0A  %7D%0A%0A  public enum SetIamPolicyResult %7B%0A    SUCCESS,%0A    ETAG_NOT_MATCH%0A  %7D%0A%0A
   class 
@@ -2706,20 +2706,28 @@
 ion;%0A%0A  
-void
+DeleteResult
  delete(
@@ -2945,20 +2945,30 @@
 ion;%0A%0A  
-void
+UndeleteResult
  undelet
@@ -3169,12 +3169,26 @@
 %0A%0A  
-void
+SetIamPolicyResult
  set

add return values to delete, undelete, and setIamPolicy