// Path: core/presentation/src/main/java/org/hesperides/core/presentation/io/platforms/PropertiesEventOutput.java
// @Value
// public class PropertiesEventOutput {
//     Long timestamp;
//     String author;
//     String comment;
//     @SerializedName("added_properties")
//     List<ValuedPropertyOutput> addedProperties;
//     @SerializedName("updated_properties")
//     List<UpdatedPropertyOutput> updatedProperties;
//     @SerializedName("removed_properties")
//     List<ValuedPropertyOutput> removedProperties;
// 
//     public static List<PropertiesEventOutput> fromViews(List<PropertiesEventView> views) {
//         return views.stream()
//                 .map(PropertiesEventOutput::new)
//                 .collect(Collectors.toList());
//     }
// 
//     public PropertiesEventOutput(PropertiesEventView view) {
//         timestamp = view.getTimestamp().toEpochMilli();
//         author = view.getAuthor();
//         comment = view.getComment();
//         addedProperties = ValuedPropertyOutput.fromViews(view.getAddedProperties());
//         updatedProperties = UpdatedPropertyOutput.fromViews(view.getUpdatedProperties());
//         removedProperties = ValuedPropertyOutput.fromViews(view.getRemovedProperties());
//     }
// 
//     @Value
//     @AllArgsConstructor
//     public static class ValuedPropertyOutput {
//         String name;
//         String value;
// 
//         public static List<ValuedPropertyOutput> fromViews(List<ValuedPropertyView> views) {
//             return views.stream()
//                     .map(ValuedPropertyOutput::new)
//                     .collect(Collectors.toList());
//         }
// 
//         public ValuedPropertyOutput(ValuedPropertyView view) {
//             this.name = view.getName();
//             this.value = view.getValue();
//         }
//     }
// 
//     @Value
//     @AllArgsConstructor
//     public static class UpdatedPropertyOutput {
//         String name;
//         @SerializedName("old_value")
//         String oldValue;
//         @SerializedName("new_value")
//         String newValue;
// 
//         public static List<UpdatedPropertyOutput> fromViews(List<UpdatedPropertyView> views) {
//             return views.stream()
//                     .map(UpdatedPropertyOutput::new)
//                     .collect(Collectors.toList());
//         }
// 
//         public UpdatedPropertyOutput(UpdatedPropertyView view) {
//             this.name = view.getName();
//             this.oldValue = view.getOldValue();
//             this.newValue = view.getNewValue();
//         }
//     }
// }


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hesperides.core.application.platforms.PlatformUseCases;
import org.hesperides.core.application.platforms.PropertiesUseCases;
import org.hesperides.core.domain.platforms.entities.Platform;
import org.hesperides.core.domain.platforms.entities.properties.AbstractValuedProperty;
import org.hesperides.core.domain.platforms.entities.properties.diff.PropertiesDiff;
import org.hesperides.core.domain.platforms.queries.views.PropertiesEventView;
import org.hesperides.core.domain.platforms.queries.views.properties.*;
import org.hesperides.core.domain.security.entities.User;
import org.hesperides.core.presentation.io.platforms.InstancesModelOutput;
import org.hesperides.core.presentation.io.platforms.PropertiesEventOutput;
import org.hesperides.core.presentation.io.platforms.properties.*;
import org.hesperides.core.presentation.io.platforms.properties.diff.PropertiesDiffOutput;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.hesperides.core.domain.platforms.entities.properties.diff.PropertiesDiff.ComparisonMode;
        Platform.Key platformKey = new Platform.Key(applicationName, platformName);
        User authenticatedUser = new User(authentication);

        if (StringUtils.isEmpty(propertiesPath)) {
            // tous les modules
            platformUseCases.getPlatform(platformKey).findActiveDeployedModules()
                    .forEach(module -> propertiesUseCases.purgeUnusedProperties(platformKey, module.getPropertiesPath(), authenticatedUser));
        } else {
            // un seul module
            propertiesUseCases.purgeUnusedProperties(platformKey, propertiesPath, authenticatedUser);
        }

        return ResponseEntity.noContent().build();
    }

    @ApiOperation("Get detailed properties of a platform or a deployed module")
    @GetMapping("/{application_name}/platforms/{platform_name}/detailed_properties")
    public ResponseEntity<PlatformDetailedPropertiesOutput> getDetailedProperties(Authentication authentication,
                                                                                  @PathVariable("application_name") final String applicationName,
                                                                                  @PathVariable("platform_name") final String platformName,
                                                                                  @RequestParam(value = "properties_path", required = false) final String propertiesPath) {
        Platform.Key platformKey = new Platform.Key(applicationName, platformName);
        User user = new User(authentication);
        PlatformDetailedPropertiesView platformDetailedPropertiesView = propertiesUseCases.getDetailedProperties(platformKey, propertiesPath, user);
        PlatformDetailedPropertiesOutput platformDetailedPropertiesOutput = new PlatformDetailedPropertiesOutput(platformDetailedPropertiesView);
        return ResponseEntity.ok(platformDetailedPropertiesOutput);
    }

    @ApiOperation("Get the history of raw values for module properties or global properties")
    @GetMapping("/{application_name}/platforms/{platform_name:.+}/properties/events")
// Path: core/presentation/src/main/java/org/hesperides/core/presentation/io/platforms/PropertiesEventOutput.java
// @Value
// public class PropertiesEventOutput {
//     Long timestamp;
//     String author;
//     String comment;
//     @SerializedName("added_properties")
//     List<ValuedPropertyOutput> addedProperties;
//     @SerializedName("updated_properties")
//     List<UpdatedPropertyOutput> updatedProperties;
//     @SerializedName("removed_properties")
//     List<ValuedPropertyOutput> removedProperties;
// 
//     public static List<PropertiesEventOutput> fromViews(List<PropertiesEventView> views) {
//         return views.stream()
//                 .map(PropertiesEventOutput::new)
//                 .collect(Collectors.toList());
//     }
// 
//     public PropertiesEventOutput(PropertiesEventView view) {
//         timestamp = view.getTimestamp().toEpochMilli();
//         author = view.getAuthor();
//         comment = view.getComment();
//         addedProperties = ValuedPropertyOutput.fromViews(view.getAddedProperties());
//         updatedProperties = UpdatedPropertyOutput.fromViews(view.getUpdatedProperties());
//         removedProperties = ValuedPropertyOutput.fromViews(view.getRemovedProperties());
//     }
// 
//     @Value
//     @AllArgsConstructor
//     public static class ValuedPropertyOutput {
//         String name;
//         String value;
// 
//         public static List<ValuedPropertyOutput> fromViews(List<ValuedPropertyView> views) {
//             return views.stream()
//                     .map(ValuedPropertyOutput::new)
//                     .collect(Collectors.toList());
//         }
// 
//         public ValuedPropertyOutput(ValuedPropertyView view) {
//             this.name = view.getName();
//             this.value = view.getValue();
//         }
//     }
// 
//     @Value
//     @AllArgsConstructor
//     public static class UpdatedPropertyOutput {
//         String name;
//         @SerializedName("old_value")
//         String oldValue;
//         @SerializedName("new_value")
//         String newValue;
// 
//         public static List<UpdatedPropertyOutput> fromViews(List<UpdatedPropertyView> views) {
//             return views.stream()
//                     .map(UpdatedPropertyOutput::new)
//                     .collect(Collectors.toList());
//         }
// 
//         public UpdatedPropertyOutput(UpdatedPropertyView view) {
//             this.name = view.getName();
//             this.oldValue = view.getOldValue();
//             this.newValue = view.getNewValue();
//         }
//     }
// }


// Path: core/presentation/src/main/java/org/hesperides/core/presentation/controllers/PropertiesController.java
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hesperides.core.application.platforms.PlatformUseCases;
import org.hesperides.core.application.platforms.PropertiesUseCases;
import org.hesperides.core.domain.platforms.entities.Platform;
import org.hesperides.core.domain.platforms.entities.properties.AbstractValuedProperty;
import org.hesperides.core.domain.platforms.entities.properties.diff.PropertiesDiff;
import org.hesperides.core.domain.platforms.queries.views.PropertiesEventView;
import org.hesperides.core.domain.platforms.queries.views.properties.*;
import org.hesperides.core.domain.security.entities.User;
import org.hesperides.core.presentation.io.platforms.InstancesModelOutput;
import org.hesperides.core.presentation.io.platforms.PropertiesEventOutput;
import org.hesperides.core.presentation.io.platforms.properties.*;
import org.hesperides.core.presentation.io.platforms.properties.diff.PropertiesDiffOutput;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.hesperides.core.domain.platforms.entities.properties.diff.PropertiesDiff.ComparisonMode;

        Platform.Key platformKey = new Platform.Key(applicationName, platformName);
        User authenticatedUser = new User(authentication);

        if (StringUtils.isEmpty(propertiesPath)) {
            // tous les modules
            platformUseCases.getPlatform(platformKey).findActiveDeployedModules()
                    .forEach(module -> propertiesUseCases.purgeUnusedProperties(platformKey, module.getPropertiesPath(), authenticatedUser));
        } else {
            // un seul module
            propertiesUseCases.purgeUnusedProperties(platformKey, propertiesPath, authenticatedUser);
        }

        return ResponseEntity.noContent().build();
    }

    @ApiOperation("Get detailed properties of a platform or a deployed module")
    @GetMapping("/{application_name}/platforms/{platform_name}/detailed_properties")
    public ResponseEntity<PlatformDetailedPropertiesOutput> getDetailedProperties(Authentication authentication,
                                                                                  @PathVariable("application_name") final String applicationName,
                                                                                  @PathVariable("platform_name") final String platformName,
                                                                                  @RequestParam(value = "properties_path", required = false) final String propertiesPath) {
        Platform.Key platformKey = new Platform.Key(applicationName, platformName);
        User user = new User(authentication);
        PlatformDetailedPropertiesView platformDetailedPropertiesView = propertiesUseCases.getDetailedProperties(platformKey, propertiesPath, user);
        PlatformDetailedPropertiesOutput platformDetailedPropertiesOutput = new PlatformDetailedPropertiesOutput(platformDetailedPropertiesView);
        return ResponseEntity.ok(platformDetailedPropertiesOutput);
    }

    @ApiOperation("Get the history of raw values for module properties or global properties")
    @GetMapping("/{application_name}/platforms/{platform_name:.+}/properties/events")
    public ResponseEntity<List<PropertiesEventOutput>> getPropertiesEvents(Authentication authentication,