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

import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.chef.config.ChefProperties.CHEF_BOOTSTRAP_DATABAG;

import java.io.IOException;
import java.io.InputStream;
import java.security.PrivateKey;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;

import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.jclouds.chef.ChefApi;
import org.jclouds.chef.ChefContext;
import org.jclouds.chef.ChefService;
import org.jclouds.chef.config.ChefProperties;
import org.jclouds.chef.domain.BootstrapConfig;
import org.jclouds.chef.domain.Client;
import org.jclouds.chef.domain.CookbookVersion;
import org.jclouds.chef.domain.DatabagItem;
import org.jclouds.chef.domain.Environment;
import org.jclouds.chef.domain.Node;
import org.jclouds.chef.functions.BootstrapConfigForGroup;
import org.jclouds.chef.functions.GroupToBootScript;
import org.jclouds.chef.functions.RunListForGroup;
import org.jclouds.chef.strategy.CleanupStaleNodesAndClients;
import org.jclouds.chef.strategy.CreateNodeAndPopulateAutomaticAttributes;
import org.jclouds.chef.strategy.DeleteAllClientsInList;
import org.jclouds.chef.strategy.DeleteAllNodesInList;
import org.jclouds.chef.strategy.ListClients;
import org.jclouds.chef.strategy.ListCookbookVersions;
import org.jclouds.chef.strategy.ListCookbookVersionsInEnvironment;
import org.jclouds.chef.strategy.ListEnvironments;
import org.jclouds.chef.strategy.ListNodes;
import org.jclouds.chef.strategy.ListNodesInEnvironment;
import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode;
import org.jclouds.crypto.Crypto;
import org.jclouds.domain.JsonBall;
import org.jclouds.io.ByteStreams2;
import org.jclouds.io.Payloads;
import org.jclouds.io.payloads.RSADecryptingPayload;
import org.jclouds.io.payloads.RSAEncryptingPayload;
import org.jclouds.json.Json;
import org.jclouds.logging.Logger;
import org.jclouds.scriptbuilder.domain.Statement;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Supplier;
import com.google.common.collect.Maps;
import com.google.common.io.InputSupplier;

@Singleton
public class BaseChefService implements ChefService {

   private final ChefContext chefContext;
   private final ChefApi api;
   private final CleanupStaleNodesAndClients cleanupStaleNodesAndClients;
   private final CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes;
   private final DeleteAllNodesInList deleteAllNodesInList;
   private final ListNodes listNodes;
   private final DeleteAllClientsInList deleteAllClientsInList;
   private final ListClients listClients;
   private final UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode;
   private final Supplier<PrivateKey> privateKey;
   private final GroupToBootScript groupToBootScript;
   private final String databag;
   private final BootstrapConfigForGroup bootstrapConfigForGroup;
   private final RunListForGroup runListForGroup;
   private final ListCookbookVersions listCookbookVersions;
   private final ListCookbookVersionsInEnvironment listCookbookVersionsInEnvironment;
   private final ListEnvironments listEnvironments;
   private final ListNodesInEnvironment listNodesInEnvironment;
   private final Json json;
   private final Crypto crypto;

   @Resource
   @Named(ChefProperties.CHEF_LOGGER)
   protected Logger logger = Logger.NULL;

   @Inject
   protected BaseChefService(ChefContext chefContext, ChefApi api,
         CleanupStaleNodesAndClients cleanupStaleNodesAndClients,
         CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes,
         DeleteAllNodesInList deleteAllNodesInList, ListNodes listNodes, DeleteAllClientsInList deleteAllClientsInList,
         ListClients listClients, ListCookbookVersions listCookbookVersions,
         UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode, Supplier<PrivateKey> privateKey,
         @Named(CHEF_BOOTSTRAP_DATABAG) String databag, GroupToBootScript groupToBootScript,
         BootstrapConfigForGroup bootstrapConfigForGroup, RunListForGroup runListForGroup,
         ListEnvironments listEnvironments, ListNodesInEnvironment listNodesInEnvironment,
         ListCookbookVersionsInEnvironment listCookbookVersionsInEnvironment, Json json, Crypto crypto) {
      this.chefContext = checkNotNull(chefContext, "chefContext");
      this.api = checkNotNull(api, "api");
      this.cleanupStaleNodesAndClients = checkNotNull(cleanupStaleNodesAndClients, "cleanupStaleNodesAndClients");
      this.createNodeAndPopulateAutomaticAttributes = checkNotNull(createNodeAndPopulateAutomaticAttributes,
            "createNodeAndPopulateAutomaticAttributes");
      this.deleteAllNodesInList = checkNotNull(deleteAllNodesInList, "deleteAllNodesInList");
      this.listNodes = checkNotNull(listNodes, "listNodes");
      this.deleteAllClientsInList = checkNotNull(deleteAllClientsInList, "deleteAllClientsInList");
      this.listClients = checkNotNull(listClients, "listClients");
      this.listCookbookVersions = checkNotNull(listCookbookVersions, "listCookbookVersions");
      this.updateAutomaticAttributesOnNode = checkNotNull(updateAutomaticAttributesOnNode,
            "updateAutomaticAttributesOnNode");
      this.privateKey = checkNotNull(privateKey, "privateKey");
      this.groupToBootScript = checkNotNull(groupToBootScript, "groupToBootScript");
      this.databag = checkNotNull(databag, "databag");
      this.bootstrapConfigForGroup = checkNotNull(bootstrapConfigForGroup, "bootstrapConfigForGroup");
      this.runListForGroup = checkNotNull(runListForGroup, "runListForGroup");
      this.listEnvironments = checkNotNull(listEnvironments, "listEnvironments");
      this.listNodesInEnvironment = checkNotNull(listNodesInEnvironment, "listNodesInEnvironment");
      this.listCookbookVersionsInEnvironment = checkNotNull(listCookbookVersionsInEnvironment,"listCookbookVersionsInEnvironment");
      this.json = checkNotNull(json, "json");
      this.crypto = checkNotNull(crypto, "crypto");
   }

   @Override
   public ChefContext getContext() {
      return chefContext;
   }

   @Override
   public byte[] encrypt(InputSupplier<? extends InputStream> supplier) throws IOException {
      return ByteStreams2.toByteArrayAndClose(new RSAEncryptingPayload(crypto, Payloads.newPayload(supplier.getInput()), privateKey
                  .get()).openStream());
   }

   @Override
   public byte[] decrypt(InputSupplier<? extends InputStream> supplier) throws IOException {
      return ByteStreams2.toByteArrayAndClose(new RSADecryptingPayload(crypto, Payloads.newPayload(supplier.getInput()), privateKey
                  .get()).openStream());
   }

   @VisibleForTesting
   String buildBootstrapConfiguration(BootstrapConfig bootstrapConfig) {
      checkNotNull(bootstrapConfig, "bootstrapConfig must not be null");

      Map<String, Object> configMap = Maps.newLinkedHashMap();
      configMap.put("run_list", bootstrapConfig.getRunList());

      if (bootstrapConfig.getEnvironment().isPresent()) {
         configMap.put("environment", bootstrapConfig.getEnvironment().get());
      }

      if (bootstrapConfig.getAttribtues().isPresent()) {
         Map<String, Object> attributes = json.fromJson(bootstrapConfig.getAttribtues().get().toString(),
               BootstrapConfigForGroup.BOOTSTRAP_CONFIG_TYPE);
         configMap.putAll(attributes);
      }

      return json.toJson(configMap);
   }

   @Override
   public Statement createBootstrapScriptForGroup(String group) {
      return groupToBootScript.apply(group);
   }

   @Override
   public void updateBootstrapConfigForGroup(String group, BootstrapConfig bootstrapConfig) {
      try {
         api.createDatabag(databag);
      } catch (IllegalStateException e) {

      }

      String jsonConfig = buildBootstrapConfiguration(bootstrapConfig);
      DatabagItem runlist = new DatabagItem(group, jsonConfig);

      if (api.getDatabagItem(databag, group) == null) {
         api.createDatabagItem(databag, runlist);
      } else {
         api.updateDatabagItem(databag, runlist);
      }
   }

   @Override
   public List<String> getRunListForGroup(String group) {
      return runListForGroup.apply(group);
   }

   @Override
   public JsonBall getBootstrapConfigForGroup(String group) {
      return bootstrapConfigForGroup.apply(group);
   }

   @Override
   public void cleanupStaleNodesAndClients(String prefix, int secondsStale) {
      cleanupStaleNodesAndClients.execute(prefix, secondsStale);
   }

   @Override
   public Node createNodeAndPopulateAutomaticAttributes(String nodeName, Iterable<String> runList) {
      return createNodeAndPopulateAutomaticAttributes.execute(nodeName, runList);
   }

   @Override
   public void updateAutomaticAttributesOnNode(String nodeName) {
      updateAutomaticAttributesOnNode.execute(nodeName);
   }

   @Override
   public void deleteAllNodesInList(Iterable<String> names) {
      deleteAllNodesInList.execute(names);
   }

   @Override
   public void deleteAllClientsInList(Iterable<String> names) {
      deleteAllClientsInList.execute(names);
   }

   @Override
   public Iterable<? extends Node> listNodes() {
      return listNodes.execute();
   }

   @Override
   public Iterable<? extends Node> listNodes(ExecutorService executorService) {
      return listNodes.execute(executorService);
   }

   @Override
   public Iterable<? extends Client> listClients() {
      return listClients.execute();
   }

   @Override
   public Iterable<? extends Client> listClients(ExecutorService executorService) {
      return listClients.execute(executorService);
   }

   @Override
   public Iterable<? extends CookbookVersion> listCookbookVersions() {
      return listCookbookVersions.execute();
   }

   @Override public Iterable<? extends CookbookVersion> listCookbookVersions(
         ExecutorService executorService) {
      return listCookbookVersions.execute(executorService);
   }

   @Override
   public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName) {
      return listCookbookVersionsInEnvironment.execute(environmentName);
   }

   @Override
   public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName,
         ExecutorService executorService) {
      return listCookbookVersionsInEnvironment.execute(executorService, environmentName);
   }

   @Override
   public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName,
         String numVersions) {
      return listCookbookVersionsInEnvironment.execute(environmentName, numVersions);
   }

   @Override
   public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName,
         String numVersions, ExecutorService executorService) {
      return listCookbookVersionsInEnvironment.execute(executorService, environmentName, numVersions);
   }

   @Override
   public Iterable<? extends Environment> listEnvironments() {
      return listEnvironments.execute();
   }

   @Override
   public Iterable<? extends Node> listNodesInEnvironment(String environmentName) {
      return listNodesInEnvironment.execute(environmentName);
   }

   @Override
   public Iterable<? extends Node> listNodesInEnvironment(String environmentName, ExecutorService executorService) {
      return listNodesInEnvironment.execute(executorService, environmentName);
   }

}
