// Copyright (C) 2018 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.googlesource.gerrit.plugins.replication;

import static com.googlesource.gerrit.plugins.replication.GerritSshApi.GERRIT_ADMIN_PROTOCOL_PREFIX;
import static com.googlesource.gerrit.plugins.replication.ReplicationQueue.repLog;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.restapi.Url;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicHeader;
import org.eclipse.jgit.transport.CredentialItem;
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.URIish;

public class GerritRestApi implements AdminApi {

  public interface Factory {
    GerritRestApi create(URIish uri);
  }

  private final CredentialsFactory credentials;
  private final CloseableHttpClient httpClient;
  private final RemoteConfig remoteConfig;
  private final URIish uri;

  @Inject
  GerritRestApi(
      CredentialsFactory credentials,
      CloseableHttpClient httpClient,
      RemoteConfig remoteConfig,
      @Assisted URIish uri) {
    this.credentials = credentials;
    this.httpClient = httpClient;
    this.remoteConfig = remoteConfig;
    this.uri = uri;
  }

  @Override
  public boolean createProject(Project.NameKey project, String head) {
    repLog.atInfo().log("Creating project %s on %s", project, uri);
    String url = String.format("%s/a/projects/%s", toHttpUri(uri), Url.encode(project.get()));
    try {
      return httpClient
          .execute(new HttpPut(url), new HttpResponseHandler(), getContext())
          .isSuccessful();
    } catch (IOException e) {
      repLog.atSevere().withCause(e).log("Couldn't perform project creation on %s", uri);
      return false;
    }
  }

  @Override
  public boolean deleteProject(Project.NameKey project) {
    repLog.atInfo().log("Deleting project %s on %s", project, uri);
    String url = String.format("%s/a/projects/%s", toHttpUri(uri), Url.encode(project.get()));
    try {
      httpClient.execute(new HttpDelete(url), new HttpResponseHandler(), getContext());
      return true;
    } catch (IOException e) {
      repLog.atSevere().withCause(e).log("Couldn't perform project deletion on %s", uri);
    }
    return false;
  }

  @Override
  public boolean updateHead(Project.NameKey project, String newHead) {
    repLog.atInfo().log("Updating head of %s on %s", project, uri);
    String url = String.format("%s/a/projects/%s/HEAD", toHttpUri(uri), Url.encode(project.get()));
    try {
      HttpPut req = new HttpPut(url);
      req.setEntity(new StringEntity(String.format("{\"ref\": \"%s\"}", newHead), UTF_8.name()));
      req.addHeader(new BasicHeader("Content-Type", "application/json"));
      httpClient.execute(req, new HttpResponseHandler(), getContext());
      return true;
    } catch (IOException e) {
      repLog.atSevere().withCause(e).log("Couldn't perform update head on %s", uri);
    }
    return false;
  }

  private HttpClientContext getContext() {
    HttpClientContext ctx = HttpClientContext.create();
    ctx.setCredentialsProvider(adapt(credentials.create(remoteConfig.getName())));
    return ctx;
  }

  private CredentialsProvider adapt(org.eclipse.jgit.transport.CredentialsProvider cp) {
    CredentialItem.Username user = new CredentialItem.Username();
    CredentialItem.Password pass = new CredentialItem.Password();
    if (cp.supports(user, pass) && cp.get(uri, user, pass)) {
      CredentialsProvider adapted = new BasicCredentialsProvider();
      adapted.setCredentials(
          AuthScope.ANY,
          new UsernamePasswordCredentials(user.getValue(), new String(pass.getValue())));
      return adapted;
    }
    return null;
  }

  private static String toHttpUri(URIish uri) {
    String u = uri.toString();
    if (u.startsWith(GERRIT_ADMIN_PROTOCOL_PREFIX)) {
      u = u.substring(GERRIT_ADMIN_PROTOCOL_PREFIX.length());
    }
    if (u.endsWith("/")) {
      return u.substring(0, u.length() - 1);
    }
    return u;
  }
}
