// 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.httpd.rpc;

import com.google.gerrit.common.errors.CorruptEntityException;
import com.google.gerrit.common.errors.InvalidQueryException;
import com.google.gerrit.common.errors.NoSuchEntityException;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.OrmRuntimeException;
import com.google.inject.Provider;

/** Support for services which require a {@link ReviewDb} instance. */
public class BaseServiceImplementation {
  private final Provider<ReviewDb> schema;
  private final Provider<? extends CurrentUser> currentUser;

  protected BaseServiceImplementation(final Provider<ReviewDb> schema,
      final Provider<? extends CurrentUser> currentUser) {
    this.schema = schema;
    this.currentUser = currentUser;
  }

  protected Account.Id getAccountId() {
    CurrentUser u = currentUser.get();
    if (u instanceof IdentifiedUser) {
      return ((IdentifiedUser) u).getAccountId();
    }
    return null;
  }

  protected CurrentUser getCurrentUser() {
    return currentUser.get();
  }

  /**
   * Executes <code>action.run</code> with an active ReviewDb connection.
   * <p>
   * A database handle is automatically opened and closed around the action's
   * {@link Action#run(ReviewDb)} method. OrmExceptions are caught and passed
   * into the onFailure method of the callback.
   *
   * @param <T> type of result the callback expects.
   * @param callback the callback that will receive the result.
   * @param action the action logic to perform.
   */
  protected <T> void run(final AsyncCallback<T> callback, final Action<T> action) {
    try {
      final T r = action.run(schema.get());
      if (r != null) {
        callback.onSuccess(r);
      }
    } catch (InvalidQueryException e) {
      callback.onFailure(e);
    } catch (NoSuchProjectException e) {
      if (e.getMessage() != null) {
        callback.onFailure(new NoSuchEntityException(e.getMessage()));
      } else {
        callback.onFailure(new NoSuchEntityException());
      }
    } catch (NoSuchGroupException e) {
      callback.onFailure(new NoSuchEntityException());
    } catch (OrmRuntimeException e) {
      Exception ex = e;
      if (e.getCause() instanceof OrmException) {
        ex = (OrmException) e.getCause();
      }
      handleOrmException(callback, ex);
    } catch (OrmException e) {
      handleOrmException(callback, e);
    } catch (Failure e) {
      if (e.getCause() instanceof NoSuchProjectException
          || e.getCause() instanceof NoSuchChangeException) {
        callback.onFailure(new NoSuchEntityException());

      } else {
        callback.onFailure(e.getCause());
      }
    }
  }

  private static <T> void handleOrmException(
      final AsyncCallback<T> callback, Exception e) {
    if (e.getCause() instanceof Failure) {
      callback.onFailure(e.getCause().getCause());
    } else if (e.getCause() instanceof CorruptEntityException) {
      callback.onFailure(e.getCause());
    } else if (e.getCause() instanceof NoSuchEntityException) {
      callback.onFailure(e.getCause());
    } else {
      callback.onFailure(e);
    }
  }

  /** Exception whose cause is passed into onFailure. */
  public static class Failure extends Exception {
    private static final long serialVersionUID = 1L;

    public Failure(final Throwable why) {
      super(why);
    }
  }

  /** Arbitrary action to run with a database connection. */
  public static interface Action<T> {
    /**
     * Perform this action, returning the onSuccess value.
     *
     * @param db an open database handle to be used by this connection.
     * @return he value to pass to {@link AsyncCallback#onSuccess(Object)}.
     * @throws OrmException any schema based action failed.
     * @throws Failure cause is given to
     *         {@link AsyncCallback#onFailure(Throwable)}.
     * @throws NoSuchProjectException
     * @throws NoSuchGroupException
     * @throws InvalidQueryException
     */
    T run(ReviewDb db) throws OrmException, Failure, NoSuchProjectException,
        NoSuchGroupException, InvalidQueryException;
  }
}
