// Path: src/main/java/org/javiermf/features/models/ProductConfiguration.java
// @Entity
// public class ProductConfiguration {
// 
//     @Id
//     @GeneratedValue
//     Long id;
// 
//     @Column(nullable = false)
//     String name;
// 
//     @Column
//     Boolean valid = true;
// 
//     @JsonIgnore
//     @ManyToOne
//     Product product;
// 
//     @ManyToMany(fetch = FetchType.EAGER)
//     Set<Feature> activedFeatures = new HashSet<Feature>();
// 
//     public Set<Feature> getActivedFeatures() {
//         return activedFeatures;
//     }
// 
//     public Set<String> availableFeatures() {
//         return collectFeatureNames(product.getProductFeatures());
//     }
// 
//     private Set<String> collectFeatureNames(Set<Feature> featuresSet) {
//         Set<String> features = new HashSet<String>();
//         for (Feature feature : featuresSet) {
//             features.add(feature.name);
//         }
// 
//         return features;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public Product getProduct() {
//         return product;
//     }
// 
//     public void setProduct(Product product) {
//         this.product = product;
//     }
// 
//     public Set<String> activedFeatures() {
//         return collectFeatureNames(activedFeatures);
//     }
// 
//     public Boolean isValid() {
//         return valid;
//     }
// 
//     public void setValid(Boolean valid) {
//         this.valid = valid;
//     }
// 
//     public void active(Feature feature) {
//         activedFeatures.add(feature);
// 
//     }
// 
//     public void deactive(Feature feature) {
//         activedFeatures.remove(feature);
//     }
// 
//     public void active(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         active(feature);
//     }
// 
//     public void deactive(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         deactive(feature);
//     }
// 
//     public boolean hasActiveFeature(String featureName) {
//         return activedFeatures().contains(featureName);
//     }
// }
// 
// Path: src/main/java/org/javiermf/features/services/ProductsConfigurationsService.java
// @Service
// public class ProductsConfigurationsService {
// 
//     @Autowired
//     ProductsConfigurationsDAO productsConfigurationsDAO;
// 
//     @Autowired
//     ProductsService productsService;
// 
//     @Autowired
//     ConfigurationEvaluator configurationEvaluator;
// 
//     public List<String> getConfigurationsNamesForProduct(String productName) {
//         List<String> configurationsForProduct = new ArrayList<String>();
// 
//         for (ProductConfiguration productConfiguration : productsConfigurationsDAO.findByProductName(productName)) {
//             configurationsForProduct.add(productConfiguration.getName());
//         }
// 
//         return configurationsForProduct;
//     }
// 
//     public ProductConfiguration findByNameAndProductName(String productName, String configurationName) {
//         return productsConfigurationsDAO.findByNameAndProductName(productName, configurationName);
//     }
// 
//     public List<String> getConfigurationActivedFeaturesNames(String productName, String configurationName) {
//         ProductConfiguration productConfiguration = productsConfigurationsDAO.findByNameAndProductName(productName, configurationName);
//         List<String> featureNames = new ArrayList<String>();
//         for (Feature feature : productConfiguration.getActivedFeatures()) {
//             featureNames.add(feature.getName());
//         }
//         return featureNames;
//     }
// 
// 
//     public void add(String productName, String configurationName) {
//         Product product = productsService.findByName(productName);
// 
//         ProductConfiguration configuration = new ProductConfiguration();
//         configuration.setName(configurationName);
//         configuration.setProduct(product);
//         productsConfigurationsDAO.insert(configuration);
//     }
// 
//     public void deleteByName(String productName, String configurationName) {
//         productsConfigurationsDAO.deleteConfigurationForProduct(productName, configurationName);
// 
//     }
// 
//     @Transactional
//     public EvaluationResult removeFeatureFromConfiguration(String productName, String configurationName, String featureName) {
//         ProductConfiguration configuration = productsConfigurationsDAO.findByNameAndProductName(productName, configurationName);
//         configuration.deactive(featureName);
// 
//         return evaluateAndUpdateConfiguration(configuration);
//     }
// 
// 
//     @Transactional
//     public EvaluationResult addFeatureFromConfiguration(String productName, String configurationName, String featureName) {
//         ProductConfiguration configuration = productsConfigurationsDAO.findByNameAndProductName(productName, configurationName);
//         if (configuration.hasActiveFeature(featureName)) {
//             throw new DuplicatedObjectException(featureName);
//         }
//         configuration.active(featureName);
// 
//         return evaluateAndUpdateConfiguration(configuration);
//     }
// 
//     private EvaluationResult evaluateAndUpdateConfiguration(ProductConfiguration configuration) {
//         Product product = configuration.getProduct();
//         EvaluationResult evaluationResult = configurationEvaluator.evaluateConfiguration(configuration, product.getProductFeatureConstraints());
//         configuration.setValid(evaluationResult.isValid);
//         return evaluationResult;
//     }
// }


import org.javiermf.features.models.ProductConfiguration;
import org.javiermf.features.services.ProductsConfigurationsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
package org.javiermf.features.services.rest;



@Component
@Produces("application/json")
public class ProductsConfigurationResource {

    @Autowired
    ProductsConfigurationsService configurationsService;

    @Autowired
    ProductsConfigurationFeaturesResource productsConfigurationFeaturesResource;

    @GET
    public List<String> getConfigurationsForProduct(@PathParam("productName") String productName) {
        return configurationsService.getConfigurationsNamesForProduct(productName);

    }

    @Path("/{configurationName}")
    @GET
// Path: src/main/java/org/javiermf/features/models/ProductConfiguration.java
// @Entity
// public class ProductConfiguration {
// 
//     @Id
//     @GeneratedValue
//     Long id;
// 
//     @Column(nullable = false)
//     String name;
// 
//     @Column
//     Boolean valid = true;
// 
//     @JsonIgnore
//     @ManyToOne
//     Product product;
// 
//     @ManyToMany(fetch = FetchType.EAGER)
//     Set<Feature> activedFeatures = new HashSet<Feature>();
// 
//     public Set<Feature> getActivedFeatures() {
//         return activedFeatures;
//     }
// 
//     public Set<String> availableFeatures() {
//         return collectFeatureNames(product.getProductFeatures());
//     }
// 
//     private Set<String> collectFeatureNames(Set<Feature> featuresSet) {
//         Set<String> features = new HashSet<String>();
//         for (Feature feature : featuresSet) {
//             features.add(feature.name);
//         }
// 
//         return features;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public Product getProduct() {
//         return product;
//     }
// 
//     public void setProduct(Product product) {
//         this.product = product;
//     }
// 
//     public Set<String> activedFeatures() {
//         return collectFeatureNames(activedFeatures);
//     }
// 
//     public Boolean isValid() {
//         return valid;
//     }
// 
//     public void setValid(Boolean valid) {
//         this.valid = valid;
//     }
// 
//     public void active(Feature feature) {
//         activedFeatures.add(feature);
// 
//     }
// 
//     public void deactive(Feature feature) {
//         activedFeatures.remove(feature);
//     }
// 
//     public void active(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         active(feature);
//     }
// 
//     public void deactive(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         deactive(feature);
//     }
// 
//     public boolean hasActiveFeature(String featureName) {
//         return activedFeatures().contains(featureName);
//     }
// }
// 
// Path: src/main/java/org/javiermf/features/services/ProductsConfigurationsService.java
// @Service
// public class ProductsConfigurationsService {
// 
//     @Autowired
//     ProductsConfigurationsDAO productsConfigurationsDAO;
// 
//     @Autowired
//     ProductsService productsService;
// 
//     @Autowired
//     ConfigurationEvaluator configurationEvaluator;
// 
//     public List<String> getConfigurationsNamesForProduct(String productName) {
//         List<String> configurationsForProduct = new ArrayList<String>();
// 
//         for (ProductConfiguration productConfiguration : productsConfigurationsDAO.findByProductName(productName)) {
//             configurationsForProduct.add(productConfiguration.getName());
//         }
// 
//         return configurationsForProduct;
//     }
// 
//     public ProductConfiguration findByNameAndProductName(String productName, String configurationName) {
//         return productsConfigurationsDAO.findByNameAndProductName(productName, configurationName);
//     }
// 
//     public List<String> getConfigurationActivedFeaturesNames(String productName, String configurationName) {
//         ProductConfiguration productConfiguration = productsConfigurationsDAO.findByNameAndProductName(productName, configurationName);
//         List<String> featureNames = new ArrayList<String>();
//         for (Feature feature : productConfiguration.getActivedFeatures()) {
//             featureNames.add(feature.getName());
//         }
//         return featureNames;
//     }
// 
// 
//     public void add(String productName, String configurationName) {
//         Product product = productsService.findByName(productName);
// 
//         ProductConfiguration configuration = new ProductConfiguration();
//         configuration.setName(configurationName);
//         configuration.setProduct(product);
//         productsConfigurationsDAO.insert(configuration);
//     }
// 
//     public void deleteByName(String productName, String configurationName) {
//         productsConfigurationsDAO.deleteConfigurationForProduct(productName, configurationName);
// 
//     }
// 
//     @Transactional
//     public EvaluationResult removeFeatureFromConfiguration(String productName, String configurationName, String featureName) {
//         ProductConfiguration configuration = productsConfigurationsDAO.findByNameAndProductName(productName, configurationName);
//         configuration.deactive(featureName);
// 
//         return evaluateAndUpdateConfiguration(configuration);
//     }
// 
// 
//     @Transactional
//     public EvaluationResult addFeatureFromConfiguration(String productName, String configurationName, String featureName) {
//         ProductConfiguration configuration = productsConfigurationsDAO.findByNameAndProductName(productName, configurationName);
//         if (configuration.hasActiveFeature(featureName)) {
//             throw new DuplicatedObjectException(featureName);
//         }
//         configuration.active(featureName);
// 
//         return evaluateAndUpdateConfiguration(configuration);
//     }
// 
//     private EvaluationResult evaluateAndUpdateConfiguration(ProductConfiguration configuration) {
//         Product product = configuration.getProduct();
//         EvaluationResult evaluationResult = configurationEvaluator.evaluateConfiguration(configuration, product.getProductFeatureConstraints());
//         configuration.setValid(evaluationResult.isValid);
//         return evaluationResult;
//     }
// }


// Path: src/main/java/org/javiermf/features/services/rest/ProductsConfigurationResource.java
import org.javiermf.features.models.ProductConfiguration;
import org.javiermf.features.services.ProductsConfigurationsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;

package org.javiermf.features.services.rest;



@Component
@Produces("application/json")
public class ProductsConfigurationResource {

    @Autowired
    ProductsConfigurationsService configurationsService;

    @Autowired
    ProductsConfigurationFeaturesResource productsConfigurationFeaturesResource;

    @GET
    public List<String> getConfigurationsForProduct(@PathParam("productName") String productName) {
        return configurationsService.getConfigurationsNamesForProduct(productName);

    }

    @Path("/{configurationName}")
    @GET
    public ProductConfiguration getConfigurationWithNameForProduct(@PathParam("productName") String productName,