/*
 * 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.http.functions;

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

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;

import javax.annotation.Resource;

import org.jclouds.http.HttpResponse;
import org.jclouds.json.internal.GsonWrapper;
import org.jclouds.logging.Logger;
import org.jclouds.util.Closeables2;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.Atomics;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.inject.TypeLiteral;

public class ParseFirstJsonValueNamed<T> implements Function<HttpResponse, T> {

   @Resource
   protected Logger logger = Logger.NULL;

   private final GsonWrapper json;
   private final TypeLiteral<T> type;
   private final ImmutableSet<String> nameChoices;

   /**
    * @param nameChoices
    *           tried in order, first match wins
    */
   public ParseFirstJsonValueNamed(GsonWrapper json, TypeLiteral<T> type, String... nameChoices) {
      this.json = checkNotNull(json, "json");
      this.type = checkNotNull(type, "type");
      this.nameChoices = ImmutableSet.copyOf(checkNotNull(nameChoices, "nameChoices"));
   }

   @Override
   public T apply(HttpResponse arg0) {
      if (arg0.getPayload() == null)
         return nothing();
      JsonReader reader = null;
      try {
         reader = new JsonReader(new InputStreamReader(arg0.getPayload().getInput()));
         // in case keys are not in quotes
         reader.setLenient(true);
         AtomicReference<String> name = Atomics.newReference();
         JsonToken token = reader.peek();
         for (; token != JsonToken.END_DOCUMENT && nnn(reader, token, name); token = skipAndPeek(token, reader)) {
         }
         if (name.get() == null) {
            logger.trace("did not object named %s in json from response %s", nameChoices, arg0);
            return nothing();
         } else if (nameChoices.contains(name.get())) {
            return json.delegate().<T> fromJson(reader, type.getType());
         } else {
            return nothing();
         }
      } catch (IOException e) {
         throw new RuntimeException(String.format(
               "error reading from stream, parsing object named %s from http response %s", nameChoices, arg0), e);
      } finally {
         Closeables2.closeQuietly(reader);
         arg0.getPayload().release();
      }
   }

   @SuppressWarnings("unchecked")
   private T nothing() {
      if (type.getRawType().isAssignableFrom(Set.class))
         return (T) ImmutableSet.of();
      else if (type.getRawType().isAssignableFrom(List.class))
         return (T) ImmutableList.of();
      else if (type.getRawType().isAssignableFrom(Map.class))
         return (T) ImmutableMap.of();
      return null;
   }

   private boolean nnn(JsonReader reader, JsonToken token, AtomicReference<String> name) throws IOException {
      if (token == JsonToken.NAME) {
         String name2 = reader.nextName();
         if (nameChoices.contains(name2)) {
            name.set(name2);
            return false;
         }
      }
      return true;

   }

   private JsonToken skipAndPeek(JsonToken token, JsonReader reader) throws IOException {
      switch (token) {
      case BEGIN_ARRAY:
         reader.beginArray();
         break;
      case END_ARRAY:
         reader.endArray();
         break;
      case BEGIN_OBJECT:
         reader.beginObject();
         break;
      case END_OBJECT:
         reader.endObject();
         break;
      case NAME:
         // NOTE that we have already advanced on NAME in the eval block;
         break;
      case STRING:
         reader.nextString();
         break;
      case NUMBER:
         reader.nextString();
         break;
      case BOOLEAN:
         reader.nextBoolean();
         break;
      case NULL:
         reader.nextNull();
         break;
      case END_DOCUMENT:
         break;
      }
      return reader.peek();
   }
}
