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

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Iterables.contains;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.get;
import static org.jclouds.cloudstack.options.DeployVirtualMachineOptions.Builder.displayName;
import static org.jclouds.cloudstack.options.ListTemplatesOptions.Builder.id;
import static org.jclouds.cloudstack.predicates.TemplatePredicates.isReady;
import static org.jclouds.cloudstack.predicates.ZonePredicates.supportsSecurityGroups;
import static org.jclouds.ssh.SshKeys.fingerprintPrivateKey;

import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.common.primitives.Ints;
import org.jclouds.cloudstack.CloudStackApi;
import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.Capabilities;
import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.NIC;
import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.NetworkType;
import org.jclouds.cloudstack.domain.Project;
import org.jclouds.cloudstack.domain.PublicIPAddress;
import org.jclouds.cloudstack.domain.SecurityGroup;
import org.jclouds.cloudstack.domain.ServiceOffering;
import org.jclouds.cloudstack.domain.SshKeyPair;
import org.jclouds.cloudstack.domain.Tag;
import org.jclouds.cloudstack.domain.Template;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.domain.Zone;
import org.jclouds.cloudstack.domain.ZoneAndName;
import org.jclouds.cloudstack.domain.ZoneSecurityGroupNamePortsCidrs;
import org.jclouds.cloudstack.features.TemplateApi;
import org.jclouds.cloudstack.functions.CreateFirewallRulesForIP;
import org.jclouds.cloudstack.functions.CreatePortForwardingRulesForIP;
import org.jclouds.cloudstack.functions.StaticNATVirtualMachineInNetwork;
import org.jclouds.cloudstack.functions.StaticNATVirtualMachineInNetwork.Factory;
import org.jclouds.cloudstack.options.CreateTagsOptions;
import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
import org.jclouds.cloudstack.options.ListFirewallRulesOptions;
import org.jclouds.cloudstack.options.ListTemplatesOptions;
import org.jclouds.cloudstack.strategy.BlockUntilJobCompletesAndReturnResult;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull;
import org.jclouds.compute.functions.GroupNamingConvention;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.logging.Logger;

/**
 * defines the connection between the {@link CloudStackApi} implementation
 * and the jclouds {@link ComputeService}
 */
@Singleton
public class CloudStackComputeServiceAdapter implements
   ComputeServiceAdapter<VirtualMachine, ServiceOffering, Template, Zone> {

   @Resource
   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
   protected Logger logger = Logger.NULL;

   private final CloudStackApi client;
   private final Predicate<String> jobComplete;
   private final Supplier<Map<String, Network>> networkSupplier;
   private final Supplier<Map<String, Project>> projectSupplier;
   private final BlockUntilJobCompletesAndReturnResult blockUntilJobCompletesAndReturnResult;
   private final Factory staticNATVMInNetwork;
   private final CreatePortForwardingRulesForIP setupPortForwardingRulesForIP;
   private final CreateFirewallRulesForIP setupFirewallRulesForIP;
   private final LoadingCache<String, Set<IPForwardingRule>> vmToRules;
   private final Map<String, Credentials> credentialStore;
   private final Map<NetworkType, ? extends OptionsConverter> optionsConverters;
   private final Supplier<LoadingCache<String, Zone>> zoneIdToZone;
   private final LoadingCache<ZoneAndName, SecurityGroup> securityGroupCache;
   private final LoadingCache<String, SshKeyPair> keyPairCache;
   private final GroupNamingConvention.Factory namingConvention;
   private final GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull credentialsProvider;

   @Inject
   public CloudStackComputeServiceAdapter(CloudStackApi client, Predicate<String> jobComplete,
                                          @Memoized Supplier<Map<String, Network>> networkSupplier,
                                          @Memoized Supplier<Map<String, Project>> projectSupplier,
                                          BlockUntilJobCompletesAndReturnResult blockUntilJobCompletesAndReturnResult,
                                          StaticNATVirtualMachineInNetwork.Factory staticNATVMInNetwork,
                                          CreatePortForwardingRulesForIP setupPortForwardingRulesForIP,
                                          CreateFirewallRulesForIP setupFirewallRulesForIP,
                                          LoadingCache<String, Set<IPForwardingRule>> vmToRules,
                                          Map<String, Credentials> credentialStore,
                                          Map<NetworkType, ? extends OptionsConverter> optionsConverters,
                                          Supplier<LoadingCache<String, Zone>> zoneIdToZone,
                                          LoadingCache<ZoneAndName, SecurityGroup> securityGroupCache,
                                          LoadingCache<String, SshKeyPair> keyPairCache,
                                          GroupNamingConvention.Factory namingConvention,
                                          GetLoginForProviderFromPropertiesAndStoreCredentialsOrReturnNull credentialsProvider) {
      this.client = checkNotNull(client, "client");
      this.jobComplete = checkNotNull(jobComplete, "jobComplete");
      this.networkSupplier = checkNotNull(networkSupplier, "networkSupplier");
      this.projectSupplier = checkNotNull(projectSupplier, "projectSupplier");
      this.blockUntilJobCompletesAndReturnResult = checkNotNull(blockUntilJobCompletesAndReturnResult,
         "blockUntilJobCompletesAndReturnResult");
      this.staticNATVMInNetwork = checkNotNull(staticNATVMInNetwork, "staticNATVMInNetwork");
      this.setupPortForwardingRulesForIP = checkNotNull(setupPortForwardingRulesForIP, "setupPortForwardingRulesForIP");
      this.setupFirewallRulesForIP = checkNotNull(setupFirewallRulesForIP, "setupFirewallRulesForIP");
      this.vmToRules = checkNotNull(vmToRules, "vmToRules");
      this.credentialStore = checkNotNull(credentialStore, "credentialStore");
      this.securityGroupCache = checkNotNull(securityGroupCache, "securityGroupCache");
      this.keyPairCache = checkNotNull(keyPairCache, "keyPairCache");
      this.optionsConverters = optionsConverters;
      this.zoneIdToZone = zoneIdToZone;
      this.namingConvention = namingConvention;
      this.credentialsProvider = credentialsProvider;
   }

   @Override
   public NodeAndInitialCredentials<VirtualMachine> createNodeWithGroupEncodedIntoName(String group, String name,
                                                                                       org.jclouds.compute.domain.Template template) {

      checkNotNull(template, "template was null");
      checkNotNull(template.getOptions(), "template options was null");
      checkArgument(template.getOptions().getClass().isAssignableFrom(CloudStackTemplateOptions.class),
         "options class %s should have been assignable from CloudStackTemplateOptions", template.getOptions()
         .getClass());
      Map<String, Network> networks = networkSupplier.get();

      final String zoneId = template.getLocation().getId();
      Zone zone = zoneIdToZone.get().getUnchecked(zoneId);

      CloudStackTemplateOptions templateOptions = template.getOptions().as(CloudStackTemplateOptions.class);

      checkState(optionsConverters.containsKey(zone.getNetworkType()), "no options converter configured for network type %s", zone.getNetworkType());
      DeployVirtualMachineOptions options = displayName(name).name(name);
      if (templateOptions.getAccount() != null) {
          options.accountInDomain(templateOptions.getAccount(), templateOptions.getDomainId());
      } else if (templateOptions.getDomainId() != null) {
          options.domainId(templateOptions.getDomainId());
      }

      OptionsConverter optionsConverter = optionsConverters.get(zone.getNetworkType());
      options = optionsConverter.apply(templateOptions, networks, zoneId, options);

      options.group(group);

      if (templateOptions.getIpOnDefaultNetwork() != null) {
         options.ipOnDefaultNetwork(templateOptions.getIpOnDefaultNetwork());
      }

      if (!templateOptions.getIpsToNetworks().isEmpty()) {
         options.ipsToNetworks(templateOptions.getIpsToNetworks());
      }

      if (templateOptions.getUserData() != null) {
         options.userData(templateOptions.getUserData());
      }

      if (templateOptions.getKeyPair() != null) {
         SshKeyPair keyPair = null;
         if (templateOptions.getLoginPrivateKey() != null) {
            String pem = templateOptions.getLoginPrivateKey();
            keyPair = SshKeyPair.builder().name(templateOptions.getKeyPair())
               .fingerprint(fingerprintPrivateKey(pem)).privateKey(pem).build();
            keyPairCache.asMap().put(keyPair.getName(), keyPair);
            options.keyPair(keyPair.getName());
         } else if (client.getSSHKeyPairApi().getSSHKeyPair(templateOptions.getKeyPair()) != null) {
            keyPair = client.getSSHKeyPairApi().getSSHKeyPair(templateOptions.getKeyPair());
         }
         if (keyPair != null) {
            keyPairCache.asMap().put(keyPair.getName(), keyPair);
            options.keyPair(keyPair.getName());
         }
      } else if (templateOptions.shouldGenerateKeyPair()) {
         SshKeyPair keyPair = keyPairCache.getUnchecked(namingConvention.create()
                                                        .sharedNameForGroup(group));
         keyPairCache.asMap().put(keyPair.getName(), keyPair);
         templateOptions.keyPair(keyPair.getName());
         options.keyPair(keyPair.getName());
      }

      if (templateOptions.getDiskOfferingId() != null) {
         options.diskOfferingId(templateOptions.getDiskOfferingId());
         if (templateOptions.getDataDiskSize() > 0) {
            options.dataDiskSize(templateOptions.getDataDiskSize());
         }
      }

      if (supportsSecurityGroups().apply(zone)) {
         List<Integer> inboundPorts = Ints.asList(templateOptions.getInboundPorts());

         if (templateOptions.getSecurityGroupIds().isEmpty()
             && !inboundPorts.isEmpty()
             && templateOptions.shouldGenerateSecurityGroup()) {
            String securityGroupName = namingConvention.create().sharedNameForGroup(group);
            SecurityGroup sg = securityGroupCache.getUnchecked(ZoneSecurityGroupNamePortsCidrs.builder()
                                                               .zone(zone.getId())
                                                               .name(securityGroupName)
                                                               .ports(ImmutableSet.copyOf(inboundPorts))
                                                               .cidrs(ImmutableSet.<String> of()).build());
            options.securityGroupId(sg.getId());
         }
      }

      String templateId = template.getImage().getId();
      String serviceOfferingId = template.getHardware().getId();

      logger.debug("serviceOfferingId %s, templateId %s, zoneId %s, options %s%n", serviceOfferingId, templateId,
         zoneId, options);
      AsyncCreateResponse job = client.getVirtualMachineApi().deployVirtualMachineInZone(zoneId, serviceOfferingId,
         templateId, options);
      VirtualMachine vm = blockUntilJobCompletesAndReturnResult.<VirtualMachine>apply(job);
      logger.debug("--- virtualmachine: %s", vm);
      LoginCredentials credentials = credentialsProvider.get();
      if (credentials == null || credentials.getUser() == null) {
         LoginCredentials.Builder credentialsBuilder = LoginCredentials.builder();
         if (templateOptions.getKeyPair() != null) {
            SshKeyPair keyPair = keyPairCache.getUnchecked(templateOptions.getKeyPair());
            credentialsBuilder.privateKey(keyPair.getPrivateKey());
         } else if (vm.isPasswordEnabled()) {
            assert vm.getPassword() != null : vm;
            credentialsBuilder.password(vm.getPassword());
         }
         credentials = credentialsBuilder.build();
      }

      try {
         ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
         builder.putAll(template.getOptions().getUserMetadata());
         for (String tag : template.getOptions().getTags())
            builder.put(tag, "jclouds-empty-tag-placeholder");
         Map<String, String> common = builder.build();

         if (!common.isEmpty()) {
            logger.debug(">> adding tags %s to virtualmachine(%s)", common, vm.getId());
            CreateTagsOptions tagOptions = CreateTagsOptions.Builder.resourceIds(vm.getId())
                  .resourceType(Tag.ResourceType.USER_VM)
                  .tags(common);
            AsyncCreateResponse tagJob = client.getTagApi().createTags(tagOptions);
            awaitCompletion(tagJob.getJobId());
            logger.debug("<< tags added");
            vm = client.getVirtualMachineApi().getVirtualMachine(vm.getId());
         }
         if (templateOptions.shouldSetupStaticNat()) {
            Capabilities capabilities = client.getConfigurationApi().listCapabilities();

            NIC nic = Iterables.find(vm.getNICs(), new Predicate<NIC>() {
               @Override
               public boolean apply(NIC input) {
                  return (input == null) ? false : input.isDefault();
               }
            });
            String networkId = nic.getNetworkId();

            logger.debug(">> creating static NAT for virtualMachine(%s) in network(%s)", vm.getId(), networkId);
            PublicIPAddress ip = staticNATVMInNetwork.create(networks.get(networkId)).apply(vm);
            logger.trace("<< static NATed IPAddress(%s) to virtualMachine(%s)", ip.getId(), vm.getId());
            vm = client.getVirtualMachineApi().getVirtualMachine(vm.getId());
            List<Integer> ports = Ints.asList(templateOptions.getInboundPorts());
            if (capabilities.getCloudStackVersion().startsWith("2")) {
               logger.debug(">> setting up IP forwarding for IPAddress(%s) rules(%s)", ip.getId(), ports);
               Set<IPForwardingRule> rules = setupPortForwardingRulesForIP.apply(ip, ports);
               logger.trace("<< setup %d IP forwarding rules on IPAddress(%s)", rules.size(), ip.getId());
            } else {
               logger.debug(">> setting up firewall rules for IPAddress(%s) rules(%s)", ip.getId(), ports);
               Set<FirewallRule> rules = setupFirewallRulesForIP.apply(ip, ports);
               logger.trace("<< setup %d firewall rules on IPAddress(%s)", rules.size(), ip.getId());
            }
          }
      } catch (RuntimeException re) {
          logger.error("-- exception after node has been created, trying to destroy the created virtualMachine(%s)", vm.getId());
          try {
              destroyNode(vm.getId());
          } catch (RuntimeException re2) {
              logger.debug("-- exception in exceptionHandler while executing destroyNode for virtualMachine(%s), ignoring and rethrowing original exception", vm.getId());
          }
          throw re;
      }
      return new NodeAndInitialCredentials<VirtualMachine>(vm, vm.getId() + "", credentials);
   }

   @Override
   public Iterable<ServiceOffering> listHardwareProfiles() {
      // TODO: we may need to filter these
      return client.getOfferingApi().listServiceOfferings();
   }

   @Override
   public Iterable<Template> listImages() {
      TemplateApi templateApi = client.getTemplateApi();
      ImmutableSet.Builder<Template> templates = ImmutableSet.builder();
      templates.addAll(templateApi.listTemplates());
      for (String project : projectSupplier.get().keySet()) {
         templates.addAll(templateApi.listTemplates(ListTemplatesOptions.Builder.projectId(project)));
      }

      return filter(templates.build(), isReady());
   }

   @Override
   public Template getImage(String id) {
      return get(client.getTemplateApi().listTemplates(id(id)), 0, null);
   }

   @Override
   public Iterable<VirtualMachine> listNodes() {
      return client.getVirtualMachineApi().listVirtualMachines();
   }

   @Override
   public Iterable<VirtualMachine> listNodesByIds(final Iterable<String> ids) {
      return filter(listNodes(), new Predicate<VirtualMachine>() {

            @Override
            public boolean apply(VirtualMachine vm) {
               return contains(ids, vm.getId());
            }
         });
   }

   @Override
   public Iterable<Zone> listLocations() {
      // TODO: we may need to filter these
      return client.getZoneApi().listZones();
   }

   @Override
   public VirtualMachine getNode(String id) {
      String virtualMachineId = id;
      return client.getVirtualMachineApi().getVirtualMachine(virtualMachineId);
   }

   @Override
   public void destroyNode(String id) {
      String virtualMachineId = id;
      // There was a bug in 2.2.12 release happening when static nat IP address
      // was being released, and corresponding firewall rules were left behind.
      // So next time the same IP is allocated, it might be not be static nat
      // enabled, but there are still rules associated with it. And when you try
      // to release this IP, the release will fail.
      //
      // The bug was fixed in 2.2.13 release only, and the current system wasn't
      // updated yet.
      //
      // To avoid the issue, every time you release a static nat ip address, do
      // the following:

      // 1) Delete IP forwarding rules associated with IP.
      Set<String> ipAddresses = deleteIPForwardingRulesForVMAndReturnDistinctIPs(virtualMachineId);

      // 2) Delete firewall rules associated with IP.
      ipAddresses.addAll(deleteFirewallRulesForVMAndReturnDistinctIPs(virtualMachineId));

      // 3) Disable static nat rule for the IP.
      disableStaticNATOnIPAddresses(ipAddresses);

      // 4) Only after 1 and 2 release the IP address.
      disassociateIPAddresses(ipAddresses);

      destroyVirtualMachine(virtualMachineId);

      vmToRules.invalidate(virtualMachineId);
   }

   public void disassociateIPAddresses(Set<String> ipAddresses) {
      for (String ipAddress : ipAddresses) {
         logger.debug(">> disassociating IPAddress(%s)", ipAddress);
         client.getAddressApi().disassociateIPAddress(ipAddress);
      }
   }

   public void destroyVirtualMachine(String virtualMachineId) {

      String destroyVirtualMachine = client.getVirtualMachineApi().destroyVirtualMachine(virtualMachineId);
      if (destroyVirtualMachine != null) {
         logger.debug(">> destroying virtualMachine(%s) job(%s)", virtualMachineId, destroyVirtualMachine);
         awaitCompletion(destroyVirtualMachine);
      } else {
         logger.trace("<< virtualMachine(%s) not found", virtualMachineId);
      }

   }

   public void disableStaticNATOnIPAddresses(Set<String> ipAddresses) {
      Builder<String> jobsToTrack = ImmutableSet.builder();
      for (String ipAddress : ipAddresses) {
         String disableStaticNAT = client.getNATApi().disableStaticNATOnPublicIP(ipAddress);
         if (disableStaticNAT != null) {
            logger.debug(">> disabling static NAT IPAddress(%s) job(%s)", ipAddress, disableStaticNAT);
            jobsToTrack.add(disableStaticNAT);
         }
      }
      awaitCompletion(jobsToTrack.build());
   }

   public Set<String> deleteIPForwardingRulesForVMAndReturnDistinctIPs(String virtualMachineId) {
      Builder<String> jobsToTrack = ImmutableSet.builder();

      // immutable doesn't permit duplicates
      Set<String> ipAddresses = Sets.newLinkedHashSet();

      Set<IPForwardingRule> forwardingRules = client.getNATApi().getIPForwardingRulesForVirtualMachine(
         virtualMachineId);
      for (IPForwardingRule rule : forwardingRules) {
         if (!"Deleting".equals(rule.getState())) {
            ipAddresses.add(rule.getIPAddressId());
            String deleteForwardingRule = client.getNATApi().deleteIPForwardingRule(rule.getId());
            if (deleteForwardingRule != null) {
               logger.debug(">> deleting IPForwardingRule(%s) job(%s)", rule.getId(), deleteForwardingRule);
               jobsToTrack.add(deleteForwardingRule);
            }
         }
      }
      awaitCompletion(jobsToTrack.build());
      return ipAddresses;
   }

   public Set<String> deleteFirewallRulesForVMAndReturnDistinctIPs(String virtualMachineId) {
      // immutable doesn't permit duplicates
      Set<String> ipAddresses = Sets.newLinkedHashSet();

      String publicIpId = client.getVirtualMachineApi().getVirtualMachine(virtualMachineId).getPublicIPId();
      if (publicIpId != null) {
         Set<FirewallRule> firewallRules = client.getFirewallApi()
            .listFirewallRules(ListFirewallRulesOptions.Builder.ipAddressId(client.getVirtualMachineApi().getVirtualMachine(virtualMachineId).getPublicIPId()));

         for (FirewallRule rule : firewallRules) {
            if (rule.getState() != FirewallRule.State.DELETING) {
               ipAddresses.add(rule.getIpAddressId());
               client.getFirewallApi().deleteFirewallRule(rule.getId());
               logger.debug(">> deleting FirewallRule(%s)", rule.getId());
            }
         }
      }
      return ipAddresses;
   }

   public void awaitCompletion(Iterable<String> jobs) {
      logger.debug(">> awaiting completion of jobs(%s)", jobs);
      for (String job : jobs)
         awaitCompletion(job);
      logger.trace("<< completed jobs(%s)", jobs);
   }

   public void awaitCompletion(String job) {
      boolean completed = jobComplete.apply(job);
      logger.trace("<< job(%s) complete(%s)", job, completed);
   }

   @Override
   public void rebootNode(String id) {
      String virtualMachineId = id;
      String job = client.getVirtualMachineApi().rebootVirtualMachine(virtualMachineId);
      if (job != null) {
         logger.debug(">> rebooting virtualMachine(%s) job(%s)", virtualMachineId, job);
         awaitCompletion(job);
      }
   }

   @Override
   public void resumeNode(String id) {
      String virtualMachineId = id;
      String job = client.getVirtualMachineApi().startVirtualMachine(id);
      if (job != null) {
         logger.debug(">> starting virtualMachine(%s) job(%s)", virtualMachineId, job);
         awaitCompletion(job);
      }
   }

   @Override
   public void suspendNode(String id) {
      String virtualMachineId = id;
      String job = client.getVirtualMachineApi().stopVirtualMachine(id);
      if (job != null) {
         logger.debug(">> stopping virtualMachine(%s) job(%s)", virtualMachineId, job);
         awaitCompletion(job);
      }
   }

}
