// Copyright 2017 The Bazel Authors. 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.devtools.build.lib.buildeventservice;

import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.authandtls.AuthAndTLSOptions;
import com.google.devtools.build.lib.authandtls.GoogleAuthUtils;
import com.google.devtools.build.lib.buildeventservice.client.BuildEventServiceClient;
import com.google.devtools.build.lib.buildeventservice.client.BuildEventServiceGrpcClient;
import io.grpc.ClientInterceptor;
import io.grpc.ManagedChannel;
import io.grpc.Metadata;
import io.grpc.stub.MetadataUtils;
import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import javax.annotation.Nullable;

/** Bazel's BES module. */
public class BazelBuildEventServiceModule
    extends BuildEventServiceModule<BuildEventServiceOptions> {

  @AutoValue
  abstract static class BackendConfig {
    abstract String besBackend();

    @Nullable
    abstract String besProxy();

    abstract ImmutableList<Map.Entry<String, String>> besHeaders();

    abstract AuthAndTLSOptions authAndTLSOptions();

    static BackendConfig create(
        BuildEventServiceOptions besOptions, AuthAndTLSOptions authAndTLSOptions) {
      return new AutoValue_BazelBuildEventServiceModule_BackendConfig(
          besOptions.besBackend,
          besOptions.besProxy,
          ImmutableMap.copyOf(besOptions.besHeaders).entrySet().asList(),
          authAndTLSOptions);
    }
  }

  private BuildEventServiceClient client;
  private BackendConfig config;

  @Override
  protected Class<BuildEventServiceOptions> optionsClass() {
    return BuildEventServiceOptions.class;
  }

  @Override
  protected BuildEventServiceClient getBesClient(
      BuildEventServiceOptions besOptions, AuthAndTLSOptions authAndTLSOptions) throws IOException {
    BackendConfig newConfig = BackendConfig.create(besOptions, authAndTLSOptions);
    if (client == null || !Objects.equals(config, newConfig)) {
      clearBesClient();
      config = newConfig;
      client =
          new BuildEventServiceGrpcClient(
              newGrpcChannel(config),
              GoogleAuthUtils.newCallCredentials(config.authAndTLSOptions()),
              makeGrpcInterceptor(config));
    }
    return client;
  }

  private static ClientInterceptor makeGrpcInterceptor(BackendConfig config) {
    if (config.besHeaders().isEmpty()) {
      return null;
    }
    return MetadataUtils.newAttachHeadersInterceptor(makeGrpcMetadata(config));
  }

  @VisibleForTesting
  static Metadata makeGrpcMetadata(BackendConfig config) {
    Metadata extraHeaders = new Metadata();
    for (Entry<String, String> header : config.besHeaders()) {
      extraHeaders.put(
          Metadata.Key.of(header.getKey(), Metadata.ASCII_STRING_MARSHALLER), header.getValue());
    }
    return extraHeaders;
  }

  // newGrpcChannel is only defined so it can be overridden in tests to not use a real network link.
  @VisibleForTesting
  protected ManagedChannel newGrpcChannel(BackendConfig config) throws IOException {
    return GoogleAuthUtils.newChannel(
        /*executor=*/ null,
        config.besBackend(),
        config.besProxy(),
        config.authAndTLSOptions(),
        /* interceptors= */ null);
  }

  @Override
  protected void clearBesClient() {
    if (client != null) {
      client.shutdown();
    }
    this.client = null;
    this.config = null;
  }

  private static final ImmutableSet<String> ALLOWED_COMMANDS =
      ImmutableSet.of(
          "fetch",
          "build",
          "test",
          "run",
          "query",
          "aquery",
          "cquery",
          "coverage",
          "mobile-install");

  @Override
  protected Set<String> allowedCommands(BuildEventServiceOptions besOptions) {
    return ALLOWED_COMMANDS;
  }

  @Override
  protected String getInvocationIdPrefix() {
    if (Strings.isNullOrEmpty(besOptions.besResultsUrl)) {
      return "";
    }
    return besOptions.besResultsUrl.endsWith("/")
        ? besOptions.besResultsUrl
        : besOptions.besResultsUrl + "/";
  }

  @Override
  protected String getBuildRequestIdPrefix() {
    return "";
  }
}
