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

import static com.google.common.collect.Iterables.any;
import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Iterables.getLast;
import static org.jclouds.chef.predicates.CookbookVersionPredicates.containsRecipe;
import static org.jclouds.compute.options.TemplateOptions.Builder.runScript;
import static org.jclouds.reflect.Reflection2.typeToken;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.List;

import org.jclouds.chef.ChefApi;
import org.jclouds.chef.ChefContext;
import org.jclouds.chef.compute.internal.BaseComputeServiceIntegratedChefClientLiveTest;
import org.jclouds.chef.domain.BootstrapConfig;
import org.jclouds.chef.domain.CookbookVersion;
import org.jclouds.chef.util.RunListBuilder;
import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.scriptbuilder.domain.Statement;
import org.jclouds.util.Strings2;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;

import com.google.common.reflect.TypeToken;

@Test(groups = "live", testName = "ChefComputeServiceLiveTest")
public class ChefComputeServiceLiveTest extends BaseComputeServiceIntegratedChefClientLiveTest {

   private String group;
   private String clientName;
   private Iterable<? extends NodeMetadata> nodes;

   @Test
   public void testCanUpdateRunList() throws IOException {
      String recipe = "apache2";

      Iterable<? extends CookbookVersion> cookbookVersions = view.getChefService().listCookbookVersions();

      if (any(cookbookVersions, containsRecipe(recipe))) {
         List<String> runList = new RunListBuilder().addRecipe(recipe).build();
         BootstrapConfig bootstrap = BootstrapConfig.builder().runList(runList).build();
         view.getChefService().updateBootstrapConfigForGroup(group, bootstrap);
         assertEquals(view.getChefService().getRunListForGroup(group), runList);
      } else {
         fail(String.format("recipe %s not in %s", recipe, cookbookVersions));
      }
   }

   @Test(dependsOnMethods = "testCanUpdateRunList")
   public void testRunNodesWithBootstrap() throws IOException {

      Statement bootstrap = view.getChefService().createBootstrapScriptForGroup(group);

      try {
         nodes = computeContext.getComputeService().createNodesInGroup(group, 1, runScript(bootstrap));
      } catch (RunNodesException e) {
         nodes = concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet());
      }

      for (NodeMetadata node : nodes) {
         URI uri = URI.create("http://" + getLast(node.getPublicAddresses()));
         InputStream content = computeContext.utils().http().get(uri);
         String string = Strings2.toStringAndClose(content);
         assertTrue(string.indexOf("It works!") >= 0,
               String.format("The default Apache page was not found: %s", string));
      }
   }

   @AfterClass(groups = { "integration", "live" })
   @Override
   protected void tearDownContext() {
      if (computeContext != null) {
         computeContext.getComputeService().destroyNodesMatching(NodePredicates.inGroup(group));
      }
      if (context != null) {
         view.getChefService().cleanupStaleNodesAndClients(group + "-", 1);
         ChefApi api = view.unwrapApi(ChefApi.class);
         if (clientName != null && api.getClient(clientName) != null) {
            api.deleteClient(clientName);
         }
         context.close();
      }
      super.tearDownContext();
   }

   @Override
   protected TypeToken<ChefContext> viewType() {
      return typeToken(ChefContext.class);
   }

}
