// Copyright 2016 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.remote;

import com.google.auth.Credentials;
import com.google.common.base.Ascii;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.remote.blobstore.ConcurrentMapBlobStore;
import com.google.devtools.build.lib.remote.common.SimpleBlobStore;
import com.google.devtools.build.lib.remote.disk.CombinedDiskHttpBlobStore;
import com.google.devtools.build.lib.remote.disk.OnDiskBlobStore;
import com.google.devtools.build.lib.remote.http.HttpBlobStore;
import com.google.devtools.build.lib.remote.options.RemoteOptions;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import io.netty.channel.unix.DomainSocketAddress;
import java.io.IOException;
import java.net.URI;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.Nullable;

/**
 * A factory class for providing a {@link SimpleBlobStore} to be used with {@link
 * SimpleBlobStoreActionCache}. Currently implemented with HTTP or local.
 */
public final class SimpleBlobStoreFactory {

  private SimpleBlobStoreFactory() {}

  public static SimpleBlobStore create(RemoteOptions remoteOptions, @Nullable Path casPath) {
    if (isHttpUrlOptions(remoteOptions)) {
      return createHttp(remoteOptions, /* creds= */ null);
    } else if (casPath != null) {
      return new OnDiskBlobStore(casPath);
    } else {
      return new ConcurrentMapBlobStore(new ConcurrentHashMap<>());
    }
  }

  public static SimpleBlobStore create(
      RemoteOptions options, @Nullable Credentials creds, Path workingDirectory)
      throws IOException {

    Preconditions.checkNotNull(workingDirectory, "workingDirectory");
    if (isHttpUrlOptions(options) && isDiskCache(options)) {
      return createCombinedCache(workingDirectory, options.diskCache, options, creds);
    }
    if (isHttpUrlOptions(options)) {
      return createHttp(options, creds);
    }
    if (isDiskCache(options)) {
      return createDiskCache(workingDirectory, options.diskCache);
    }
    throw new IllegalArgumentException(
        "Unrecognized RemoteOptions configuration: remote Http cache URL and/or local disk cache"
            + " options expected.");
  }

  public static boolean isRemoteCacheOptions(RemoteOptions options) {
    return isHttpUrlOptions(options) || isDiskCache(options);
  }

  private static SimpleBlobStore createHttp(RemoteOptions options, Credentials creds) {
    Preconditions.checkNotNull(options.remoteCache, "remoteCache");

    try {
      URI uri = URI.create(options.remoteCache);
      Preconditions.checkArgument(
          Ascii.toLowerCase(uri.getScheme()).startsWith("http"),
          "remoteCache should start with http");

      if (options.remoteProxy != null) {
        if (options.remoteProxy.startsWith("unix:")) {
          return HttpBlobStore.create(
              new DomainSocketAddress(options.remoteProxy.replaceFirst("^unix:", "")),
              uri,
              options.remoteTimeout,
              options.remoteMaxConnections,
              ImmutableList.copyOf(options.remoteHeaders),
              creds);
        } else {
          throw new Exception("Remote cache proxy unsupported: " + options.remoteProxy);
        }
      } else {
        return HttpBlobStore.create(
            uri,
            options.remoteTimeout,
            options.remoteMaxConnections,
            ImmutableList.copyOf(options.remoteHeaders),
            creds);
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  private static SimpleBlobStore createDiskCache(Path workingDirectory, PathFragment diskCachePath)
      throws IOException {
    Path cacheDir =
        workingDirectory.getRelative(Preconditions.checkNotNull(diskCachePath, "diskCachePath"));
    if (!cacheDir.exists()) {
      cacheDir.createDirectoryAndParents();
    }
    return new OnDiskBlobStore(cacheDir);
  }

  private static SimpleBlobStore createCombinedCache(
      Path workingDirectory, PathFragment diskCachePath, RemoteOptions options, Credentials cred)
      throws IOException {

    Path cacheDir =
        workingDirectory.getRelative(Preconditions.checkNotNull(diskCachePath, "diskCachePath"));
    if (!cacheDir.exists()) {
      cacheDir.createDirectoryAndParents();
    }

    OnDiskBlobStore diskCache = new OnDiskBlobStore(cacheDir);
    SimpleBlobStore httpCache = createHttp(options, cred);
    return new CombinedDiskHttpBlobStore(diskCache, httpCache);
  }

  private static boolean isDiskCache(RemoteOptions options) {
    return options.diskCache != null && !options.diskCache.isEmpty();
  }

  private static boolean isHttpUrlOptions(RemoteOptions options) {
    return options.remoteCache != null
        && (Ascii.toLowerCase(options.remoteCache).startsWith("http://")
            || Ascii.toLowerCase(options.remoteCache).startsWith("https://"));
  }
}
