// Copyright (C) 2015 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.gpg.api;

import com.google.gerrit.extensions.api.accounts.GpgKeyApi;
import com.google.gerrit.extensions.common.GpgKeyInfo;
import com.google.gerrit.extensions.common.PushCertificateInfo;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.gpg.GerritPushCertificateChecker;
import com.google.gerrit.gpg.PushCertificateChecker;
import com.google.gerrit.gpg.server.GpgKeys;
import com.google.gerrit.gpg.server.PostGpgKeys;
import com.google.gerrit.server.GpgException;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountResource;
import com.google.gerrit.server.api.accounts.GpgApiAdapter;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;

import org.bouncycastle.openpgp.PGPException;
import org.eclipse.jgit.transport.PushCertificate;
import org.eclipse.jgit.transport.PushCertificateParser;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public class GpgApiAdapterImpl implements GpgApiAdapter {
  private final PostGpgKeys postGpgKeys;
  private final GpgKeys gpgKeys;
  private final GpgKeyApiImpl.Factory gpgKeyApiFactory;
  private final GerritPushCertificateChecker.Factory pushCertCheckerFactory;

  @Inject
  GpgApiAdapterImpl(
      PostGpgKeys postGpgKeys,
      GpgKeys gpgKeys,
      GpgKeyApiImpl.Factory gpgKeyApiFactory,
      GerritPushCertificateChecker.Factory pushCertCheckerFactory) {
    this.postGpgKeys = postGpgKeys;
    this.gpgKeys = gpgKeys;
    this.gpgKeyApiFactory = gpgKeyApiFactory;
    this.pushCertCheckerFactory = pushCertCheckerFactory;
  }

  @Override
  public Map<String, GpgKeyInfo> listGpgKeys(AccountResource account)
      throws RestApiException, GpgException {
    try {
      return gpgKeys.list().apply(account);
    } catch (OrmException | PGPException | IOException e) {
      throw new GpgException(e);
    }
  }

  @Override
  public Map<String, GpgKeyInfo> putGpgKeys(AccountResource account,
      List<String> add, List<String> delete)
      throws RestApiException, GpgException {
    PostGpgKeys.Input in = new PostGpgKeys.Input();
    in.add = add;
    in.delete = delete;
    try {
      return postGpgKeys.apply(account, in);
    } catch (PGPException | OrmException | IOException e) {
      throw new GpgException(e);
    }
  }

  @Override
  public GpgKeyApi gpgKey(AccountResource account, IdString idStr)
      throws RestApiException, GpgException {
    try {
      return gpgKeyApiFactory.create(gpgKeys.parse(account, idStr));
    } catch (PGPException | OrmException | IOException e) {
      throw new GpgException(e);
    }
  }

  @Override
  public PushCertificateInfo checkPushCertificate(String certStr,
      IdentifiedUser expectedUser) throws GpgException {
    try {
      PushCertificate cert = PushCertificateParser.fromString(certStr);
      PushCertificateChecker.Result result = pushCertCheckerFactory
          .create(expectedUser)
          .setCheckNonce(false)
          .check(cert);
      PushCertificateInfo info = new PushCertificateInfo();
      info.certificate = certStr;
      info.key = GpgKeys.toJson(result.getPublicKey(), result.getCheckResult());
      return info;
    } catch (IOException e) {
      throw new GpgException(e);
    }
  }

}
