package io.cloudsoft.tosca.a4c.brooklyn.spec;

import javax.inject.Inject;

import org.apache.brooklyn.api.catalog.CatalogItem;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.software.base.SameServerEntity;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess;
import org.apache.brooklyn.entity.stock.BasicApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.google.common.base.Functions;

import io.cloudsoft.tosca.a4c.brooklyn.Alien4CloudApplication;
import io.cloudsoft.tosca.a4c.brooklyn.Alien4CloudFacade;
import io.cloudsoft.tosca.a4c.brooklyn.ToscaApplication;
import io.cloudsoft.tosca.a4c.brooklyn.ToscaFacade;

@Component
public class Alien4CloudEntitySpecFactory implements EntitySpecFactory<Alien4CloudApplication> {

    private static final Logger LOG = LoggerFactory.getLogger(Alien4CloudEntitySpecFactory.class);

    private final ManagementContext mgmt;
    private ToscaFacade<Alien4CloudApplication> alien4CloudFacade;

    @Inject
    public Alien4CloudEntitySpecFactory(ManagementContext mgmt, ToscaFacade<Alien4CloudApplication> alien4CloudFacade) {
        this.mgmt = mgmt;
        this.alien4CloudFacade = alien4CloudFacade;
    }

    @Override
    public EntitySpec<?> create(String nodeId, Alien4CloudApplication toscaApplication) {
        // TODO: decide on how to behave if indexedNodeTemplate.getElementId is abstract.
        // Currently we create a VanillaSoftwareProcess.

        EntitySpec<?> spec;
        String type = toscaApplication.getNodeTemplate(nodeId).getType();
        CatalogItem catalogItem = CatalogUtils.getCatalogItemOptionalVersion(mgmt, type);
        if (catalogItem != null) {
            LOG.info("Found Brooklyn catalog item that match node type: " + type);
            spec = (EntitySpec<?>) mgmt.getCatalog().createSpec(catalogItem);

        } else if (isComputeType(nodeId, toscaApplication)) {
            spec = EntitySpec.create(SameServerEntity.class);
        } else {
            try {
                LOG.info("Found Brooklyn entity that match node type: " + type);
                spec = EntitySpec.create((Class<? extends Entity>) Class.forName(type));

            } catch (ClassNotFoundException e) {
                LOG.info("Cannot find any Brooklyn catalog item nor Brooklyn entities that match node type: " +
                        type + ". Defaulting to a VanillaSoftwareProcess");
                spec = EntitySpec.create(VanillaSoftwareProcess.class);
            }
        }

        return spec;
    }

    private boolean isComputeType(String nodeId, Alien4CloudApplication toscaApplication) {
        return alien4CloudFacade.isDerivedFrom(nodeId, toscaApplication, Alien4CloudFacade.COMPUTE_TYPE);
    }
}

@@ -84,49 +84,104 @@
 org.
-apache.brooklyn.api.catalog.CatalogItem
+slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0Aimport org.springframework.stereotype.Component
 ;%0A
+%0A
 impo
@@ -358,194 +358,34 @@
 lyn.
-core.catalog.internal.CatalogUtils;%0Aimport org.apache.brooklyn.core.entity.Attributes;%0Aimport org.apache.brooklyn.core.sensor.Sensors;%0Aimport org.apache.brooklyn.enricher.stock.Enrichers
+api.typereg.RegisteredType
 ;%0Aim
@@ -452,73 +452,8 @@
 ty;%0A
-import org.apache.brooklyn.entity.software.base.SoftwareProcess;%0A
 impo
@@ -523,214 +523,8 @@
 ess;
-%0Aimport org.apache.brooklyn.entity.stock.BasicApplication;%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0Aimport org.springframework.stereotype.Component;%0A%0Aimport com.google.common.base.Functions;
 %0A%0Aim
@@ -646,65 +646,8 @@
 de;%0A
-import io.cloudsoft.tosca.a4c.brooklyn.ToscaApplication;%0A
 impo
@@ -1586,24 +1586,25 @@
 Type();%0A
+%0A
         
 CatalogI
@@ -1599,83 +1599,67 @@
     
-CatalogItem catalogItem = CatalogUtils.getCatalogItemOptionalVersion(mgmt, 
+RegisteredType registeredType = mgmt.getTypeRegistry().get(
 type
@@ -1675,21 +1675,23 @@
   if
- (catalogItem
+(registeredType
  != 
@@ -1714,158 +1714,74 @@
     
-LOG.info(%22Found Brooklyn catalog item that match node type: %22 + type);%0A            spec = (EntitySpec%3C?%3E) mgmt.getCatalog().createSpec(catalogItem
+spec = mgmt.getTypeRegistry().create(registeredType, null, null
 );%0A
-%0A
     

Use Type registry rather than catalog