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

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.propagate;
import static org.jclouds.scriptbuilder.domain.Statements.appendFile;
import static org.jclouds.scriptbuilder.domain.Statements.exec;
import static org.jclouds.scriptbuilder.domain.Statements.newStatementList;

import java.lang.reflect.Type;
import java.net.URI;
import java.security.PrivateKey;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

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

import org.jclouds.chef.config.InstallChef;
import org.jclouds.chef.config.Validator;
import org.jclouds.crypto.Pems;
import org.jclouds.domain.JsonBall;
import org.jclouds.json.Json;
import org.jclouds.location.Provider;
import org.jclouds.scriptbuilder.ExitInsteadOfReturn;
import org.jclouds.scriptbuilder.domain.Statement;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Splitter;
import com.google.common.base.Supplier;
import com.google.common.cache.CacheLoader;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.inject.TypeLiteral;

/**
 * 
 * Generates a bootstrap script relevant for a particular group
 */
@Singleton
public class GroupToBootScript implements Function<String, Statement> {
   private static final Pattern newLinePattern = Pattern.compile("(\\r\\n)|(\\n)");
   
   @VisibleForTesting
   static final Type RUN_LIST_TYPE = new TypeLiteral<Map<String, List<String>>>() {
   }.getType();
   private final Supplier<URI> endpoint;
   private final Json json;
   private final CacheLoader<String, ? extends JsonBall> bootstrapConfigForGroup;
   private final Statement installChef;
   private final Optional<String> validatorName;
   private final Optional<PrivateKey> validatorCredential;

   @Inject
   public GroupToBootScript(@Provider Supplier<URI> endpoint, Json json,
         CacheLoader<String, ? extends JsonBall> bootstrapConfigForGroup,
         @InstallChef Statement installChef, @Validator Optional<String> validatorName,
         @Validator Optional<PrivateKey> validatorCredential) {
      this.endpoint = checkNotNull(endpoint, "endpoint");
      this.json = checkNotNull(json, "json");
      this.bootstrapConfigForGroup = checkNotNull(bootstrapConfigForGroup, "bootstrapConfigForGroup");
      this.installChef = checkNotNull(installChef, "installChef");
      this.validatorName = checkNotNull(validatorName, "validatorName");
      this.validatorCredential = checkNotNull(validatorCredential, validatorCredential);
   }

   @Override
   public Statement apply(String group) {
      checkNotNull(group, "group");
      String validatorClientName = validatorName.get();
      PrivateKey validatorKey = validatorCredential.get();

      JsonBall bootstrapConfig = null;
      try {
         bootstrapConfig = bootstrapConfigForGroup.load(group);
      } catch (Exception e) {
         throw propagate(e);
      }

      Map<String, JsonBall> config = json.fromJson(bootstrapConfig.toString(),
            BootstrapConfigForGroup.BOOTSTRAP_CONFIG_TYPE);
      Optional<JsonBall> environment = Optional.fromNullable(config.get("environment"));

      String chefConfigDir = "{root}etc{fs}chef";
      Statement createChefConfigDir = exec("{md} " + chefConfigDir);
      Statement createClientRb = appendFile(chefConfigDir + "{fs}client.rb", ImmutableList.of("require 'rubygems'",
            "require 'ohai'", "o = Ohai::System.new", "o.all_plugins",
            String.format("node_name \"%s-\" + o[:ipaddress]", group), "log_level :info", "log_location STDOUT",
            String.format("validation_client_name \"%s\"", validatorClientName),
            String.format("chef_server_url \"%s\"", endpoint.get())));

      Statement createValidationPem = appendFile(chefConfigDir + "{fs}validation.pem",
            Splitter.on(newLinePattern).split(Pems.pem(validatorKey)));

      String chefBootFile = chefConfigDir + "{fs}first-boot.json";
      Statement createFirstBoot = appendFile(chefBootFile, Collections.singleton(json.toJson(bootstrapConfig)));

      ImmutableMap.Builder<String, String> options = ImmutableMap.builder();
      options.put("-j", chefBootFile);
      if (environment.isPresent()) {
         options.put("-E", environment.get().toString());
      }
      String strOptions = Joiner.on(' ').withKeyValueSeparator(" ").join(options.build());
      Statement runChef = exec("chef-client " + strOptions);

      return newStatementList(new ExitInsteadOfReturn(installChef), createChefConfigDir, createClientRb, createValidationPem,
            createFirstBoot, runChef);
   }

}
