/**
   * it deletes the networks from the environment if they are not used.
   *
   * @param claudiaData
   * @param tierInstance
   * @throws InvalidEntityException
   * @throws InfrastructureException
   * @throws EntityNotFoundException
   */
  @Override
  public void deleteNetworksInTierInstance(ClaudiaData claudiaData, TierInstance tierInstance)
      throws InvalidEntityException, InfrastructureException, EntityNotFoundException {
    log.info("Delete the networks in env if there are not being used");

    List<NetworkInstance> netInsts = null;
    try {
      netInsts = getNetworkInstInEnv(tierInstance);
    } catch (EntityNotFoundException e) {
      throw new InfrastructureException("It is not possible to find the network " + e.getMessage());
    }

    tierInstance.getNetworkInstances().clear();
    tierInstanceManager.update(tierInstance);
    for (NetworkInstance network : netInsts) {
      log.info("Is network default? " + network.isDefaultNet());

      if (!network.isDefaultNet()) {
        try {
          networkInstanceManager.delete(claudiaData, network, network.getRegionName());
        } catch (Exception e) {
          log.warn(
              "It is not possible to delete  the network "
                  + network.getNetworkName()
                  + " "
                  + network.getRegionName()
                  + " "
                  + e.getMessage());
        }
      }
    }
  }
  private TierInstance insertTierInstanceBD(
      ClaudiaData claudiaData, String envName, TierInstance tierInstance)
      throws EntityNotFoundException, InvalidEntityException, AlreadyExistsEntityException,
          InfrastructureException {

    log.info(
        "Inserting in database for tier instance "
            + tierInstance.getName()
            + " "
            + tierInstance.getNetworkInstances().size()
            + " "
            + tierInstance.getTier().getName()
            + " "
            + tierInstance.getTier().getFloatingip());
    TierInstance tierInstanceDB = null;

    try {
      tierInstanceDB = tierInstanceManager.load(tierInstance.getName());
      log.warn("the tier already exists");
    } catch (EntityNotFoundException e) {
      tierInstanceDB = tierInstanceManager.create(claudiaData, envName, tierInstance);
    }
    return tierInstanceDB;
  }
 private List<NetworkInstance> getNetworkInstInEnv(TierInstance tierInstance)
     throws InvalidEntityException, EntityNotFoundException {
   List<NetworkInstance> netInst = new ArrayList<NetworkInstance>();
   // for (TierInstance tierInstance : envInstance.getTierInstances()) {
   Set<NetworkInstance> netInts = tierInstance.cloneNetworkInt();
   tierInstance.getNetworkInstances().clear();
   tierInstanceManager.update(tierInstance);
   for (NetworkInstance net : netInts) {
     if (!netInst.contains(net)) {
       netInst.add(net);
     }
   }
   // }
   return netInst;
 }
  /*
   * (non-Javadoc)
   * @see com.telefonica.euro_iaas.paasmanager.manager.InfrastructureManager# deleteEnvironment
   * (com.telefonica.euro_iaas.paasmanager.model.EnvironmentInstance)
   */
  public void deleteEnvironment(ClaudiaData claudiaData, EnvironmentInstance envInstance)
      throws InfrastructureException, InvalidEntityException, EntityNotFoundException {
    log.info("Delete environment " + envInstance.getBlueprintName());
    List<TierInstance> tierInstances = envInstance.getTierInstances();

    if (tierInstances == null) return;
    for (int i = 0; i < tierInstances.size(); i++) {
      TierInstance tierInstance = tierInstances.get(i);
      tierInstance = tierInstanceManager.loadNetworkInstnace(tierInstance.getName());
      boolean exists =
          claudiaClient.existsVMReplica(
              claudiaData,
              tierInstance.getName(),
              tierInstance.getVM(),
              tierInstance.getTier().getRegion());
      if (exists) {
        claudiaClient.undeployVMReplica(claudiaData, tierInstance);
      }
    }
  }
  public EnvironmentInstance createInfrasctuctureEnvironmentInstance(
      EnvironmentInstance environmentInstance, Set<Tier> tiers, ClaudiaData claudiaData)
      throws InfrastructureException, InvalidEntityException, EntityNotFoundException,
          AlreadyExistsEntityException {

    // Deploy MVs
    log.info(
        "Creating infrastructure for environment instance "
            + environmentInstance.getBlueprintName());

    for (Tier tier : tiers) {
      for (int numReplica = 1; numReplica <= tier.getInitialNumberInstances(); numReplica++) {
        // claudiaData.setVm(tier.getName());
        log.info("Deploying tier instance for tier " + tier.getName() + " " + tier.getRegion());
        Tier tierDB =
            tierManager.loadTierWithProductReleaseAndMetadata(
                tier.getName(), tier.getEnviromentName(), tier.getVdc());

        TierInstance tierInstance = new TierInstance();
        String name =
            generateVMName(
                environmentInstance.getBlueprintName(),
                tier.getName(),
                numReplica,
                claudiaData.getVdc());

        tierInstance.setName(name);
        tierInstance.setNumberReplica(numReplica);
        tierInstance.setVdc(claudiaData.getVdc());
        tierInstance.setStatus(Status.DEPLOYING);
        tierInstance.setTier(tierDB);
        VM vm = new VM();
        String fqn =
            claudiaData.getOrg().replace("_", ".")
                + ".customers."
                + claudiaData.getVdc()
                + ".services."
                + claudiaData.getService()
                + ".vees."
                + tier.getName()
                + ".replicas."
                + numReplica;

        String hostname =
            generateVMName(
                    claudiaData.getService(), tier.getName(), numReplica, claudiaData.getVdc())
                .toLowerCase();
        log.info("fqn " + fqn + " hostname " + hostname);
        vm.setFqn(fqn);
        vm.setHostname(hostname);
        tierInstance.setVM(vm);

        log.info("Deploy networks if required");

        log.info("Deploying tier instance for tier " + tier.getName() + " " + tier.getRegion());
        this.deployNetworks(claudiaData, tierInstance);
        log.info(
            "Number of networks "
                + tierInstance.getNetworkInstances().size()
                + " floatin ip "
                + tierInstance.getTier().getFloatingip());

        log.info("Inserting in database ");
        tierInstance =
            insertTierInstanceBD(
                claudiaData, environmentInstance.getEnvironment().getName(), tierInstance);
        log.info(
            "Return: Number of networks "
                + tierInstance.getNetworkInstances().size()
                + " floating ip "
                + tierInstance.getTier().getFloatingip());
        environmentInstance.addTierInstance(tierInstance);
        environmentInstanceDao.update(environmentInstance);

        try {
          tierInstanceManager.update(
              claudiaData, environmentInstance.getEnvironment().getName(), tierInstance);
        } catch (Exception e) {
          log.error("Error deploying a VM: " + e.getMessage());
          environmentInstance.setStatus(Status.ERROR);
          throw new InfrastructureException(e.getMessage());
        }

        log.info(
            "Tier instance name "
                + environmentInstance.getBlueprintName()
                + "-"
                + tier.getName()
                + "-"
                + numReplica);
        deployVM(claudiaData, tierInstance, numReplica, vm);

        tierInstance.setVM(vm);

        try {
          log.info("Inserting in database ");
          // tierInstance = insertTierInstanceBD(tierInstance);
          tierInstance.setStatus(Status.DEPLOYED);
          tierInstanceManager.update(
              claudiaData, environmentInstance.getEnvironment().getName(), tierInstance);
        } catch (EntityNotFoundException e) {
          log.info(
              "Entitiy NOt found: Tier " + tierInstance.getTier().getName() + " " + e.getMessage());
          throw new InfrastructureException(e);
        } catch (InvalidEntityException e) {
          throw new InfrastructureException(e);
        } catch (AlreadyExistsEntityException e) {
          throw new InfrastructureException(e);
        } catch (Exception e) {
          throw new InfrastructureException(e);
        }
      }
    }
    return environmentInstance;
  }