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

import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Throwables.propagate;
import static org.jclouds.util.Closeables2.closeQuietly;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import javax.inject.Singleton;

import org.jclouds.byon.Node;
import org.jclouds.byon.domain.YamlNode;
import org.yaml.snakeyaml.TypeDescription;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;

import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.io.ByteSource;

/**
 * Parses the following syntax.
 * 
 * <pre>
 * nodes:
 *     - id: cluster-1:
 *       name: cluster-1
 *       description: xyz
 *       hostname: cluster-1.mydomain.com
 *       location_id: virginia
 *       os_arch: x86
 *       os_family: linux
 *       os_description: redhat
 *       os_version: 5.3
 *       group: hadoop
 *       tags:
 *           - vanilla
 *       username: kelvin
 *       credential: password_or_rsa
 *         or
 *       credential_url: password_or_rsa_file ex. resource:///id_rsa will get the classpath /id_rsa; file://path/to/id_rsa
 *       sudo_password: password
 * </pre>
 */
@Singleton
public class NodesFromYamlStream implements Function<ByteSource, LoadingCache<String, Node>> {

   /**
    * Type-safe config class for YAML
    * 
    */
   public static class Config {
      public List<YamlNode> nodes;
   }

   @Override
   public LoadingCache<String, Node> apply(ByteSource source) {

      Constructor constructor = new Constructor(Config.class);

      TypeDescription nodeDesc = new TypeDescription(YamlNode.class);
      nodeDesc.putListPropertyType("tags", String.class);
      constructor.addTypeDescription(nodeDesc);

      TypeDescription configDesc = new TypeDescription(Config.class);
      configDesc.putListPropertyType("nodes", YamlNode.class);
      constructor.addTypeDescription(configDesc);
      Yaml yaml = new Yaml(constructor);
      Config config;
      InputStream in = null;
      try {
         in = source.openStream();
         config = (Config) yaml.load(in);
      } catch (IOException ioe) {
         throw propagate(ioe);
      } finally {
         closeQuietly(in);
      }
      checkState(config != null, "missing config: class");
      checkState(config.nodes != null, "missing nodes: collection");

      Map<String, Node> backingMap = Maps.uniqueIndex(Iterables.transform(config.nodes, YamlNode.toNode),
            new Function<Node, String>() {
               public String apply(Node node) {
                  return node.getId();
               }
            });
      LoadingCache<String, Node> cache = CacheBuilder.newBuilder().build(CacheLoader.from(Functions.forMap(backingMap)));
      for (String node : backingMap.keySet())
         cache.getUnchecked(node);
      return cache;
   }
}
