/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.jclouds.openstack.glance.functions;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.regex.Pattern;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.jclouds.http.HttpRequest;
import org.jclouds.json.Json;
import org.jclouds.location.Region;
import org.jclouds.rest.HttpClient;
import org.jclouds.rest.annotations.ApiVersion;
import org.jclouds.util.Strings2;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Iterables;

@Singleton
public class RegionToEndpointNegotiateVersion implements Function<Object, URI> {

   public static final String VERSION_NEGOTIATION_HEADER = "Is-Version-Negotiation-Request";

   private static final Pattern versionRegex = Pattern.compile("v[0-9]+(\\.[0-9])?[0-9]*");

   private static class VersionsJsonResponse{
      public static class Version {
         public static class Link {
            public String href;
            public String rel;
         }
         public String status;
         public String id;
         public List<Link> links;
      }
      public List<Version> versions;
   }

   private final Supplier<Map<String, Supplier<URI>>> regionToEndpointSupplier;
   private final String apiVersion;
   private final LoadingCache<URI, URI> endpointCache;

   @Inject
   public RegionToEndpointNegotiateVersion(@Region Supplier<Map<String, Supplier<URI>>> regionToEndpointSupplier,
         @ApiVersion String rawApiVersionString, final HttpClient client, final Json json) {
      this.regionToEndpointSupplier = checkNotNull(regionToEndpointSupplier, "regionToEndpointSupplier");
      if (!rawApiVersionString.startsWith("v")) {
         this.apiVersion = "v" + rawApiVersionString;
      } else {
         this.apiVersion = rawApiVersionString;
      }
      this.endpointCache = CacheBuilder.newBuilder()
         .build(
            new CacheLoader<URI, URI>() {
               public URI load(URI baseEndpointUri) {
                  try {
                     List<String> baseEndpointPathParts = Splitter.on('/').omitEmptyStrings().splitToList(baseEndpointUri.getPath());
                     if (!baseEndpointPathParts.isEmpty()
                           && versionRegex.matcher(baseEndpointPathParts.get(baseEndpointPathParts.size() - 1)).matches()) {
                        // Constructs a base URI Glance endpoint by stripping the version from the received URI
                        baseEndpointUri = new URI(baseEndpointUri.getScheme(), baseEndpointUri.getUserInfo(),
                           baseEndpointUri.getHost(), baseEndpointUri.getPort(),
                           Joiner.on('/').join(baseEndpointPathParts.subList(0, baseEndpointPathParts.size() - 1)) + "/",
                           baseEndpointUri.getQuery(), baseEndpointUri.getFragment());
                     }

                     HttpRequest negotiationRequest = HttpRequest.builder()
                        .method("GET").endpoint(baseEndpointUri)
                        .addHeader(VERSION_NEGOTIATION_HEADER, "true").build();
                     InputStream response = client.invoke(negotiationRequest).getPayload().openStream();
                     VersionsJsonResponse versions = json.fromJson(Strings2.toStringAndClose(response), VersionsJsonResponse.class);
                     for (VersionsJsonResponse.Version version : versions.versions) {
                        if (apiVersion.equals(version.id)) {
                           // We only expect one element here, we'll get an exception here if that changes
                           URI versionedEndpointUri = new URI(Iterables.getOnlyElement(version.links).href);
                           return new URI(baseEndpointUri.getScheme(), versionedEndpointUri.getUserInfo(),
                              versionedEndpointUri.getHost(), versionedEndpointUri.getPort(),
                              versionedEndpointUri.getPath(), versionedEndpointUri.getQuery(),
                              versionedEndpointUri.getFragment());
                        }
                     }
                  } catch (URISyntaxException ex) {
                     throw Throwables.propagate(ex);
                  } catch (IOException ex) {
                     throw Throwables.propagate(ex);
                  }
                  throw new UnsupportedOperationException("Glance endpoint does not support API version: " + apiVersion);
              }
         });
   }

   @Override
   public URI apply(Object from) {
      checkArgument(from instanceof String, "you must specify a region, as a String argument");
      Map<String, Supplier<URI>> regionToEndpoint = regionToEndpointSupplier.get();
      checkState(!regionToEndpoint.isEmpty(), "no region name to endpoint mappings configured!");
      checkArgument(regionToEndpoint.containsKey(from),
               "requested location %s, which is not in the configured locations: %s", from, regionToEndpoint);
      URI uri = regionToEndpointSupplier.get().get(from).get();

      try {
         return endpointCache.get(uri);
      } catch (ExecutionException ex) {
         throw Throwables.propagate(ex);
      }
    }
}
