<commit_before>package alien4cloud.rest.wizard;

import alien4cloud.application.ApplicationEnvironmentService;
import alien4cloud.application.ApplicationService;
import alien4cloud.application.ApplicationVersionService;
import alien4cloud.dao.IGenericSearchDAO;
import alien4cloud.dao.model.FacetedSearchResult;
import alien4cloud.exception.AlreadyExistException;
import alien4cloud.images.IImageDAO;
import alien4cloud.model.application.Application;
import alien4cloud.model.application.ApplicationEnvironment;
import alien4cloud.model.common.MetaPropConfiguration;
import alien4cloud.paas.model.DeploymentStatus;
import alien4cloud.rest.component.ComponentSearchRequest;
import alien4cloud.rest.model.*;
import alien4cloud.rest.wizard.model.*;
import alien4cloud.topology.TopologyDTO;
import alien4cloud.topology.TopologyService;
import alien4cloud.topology.TopologyServiceCore;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.alien4cloud.tosca.catalog.index.ArchiveIndexer;
import org.alien4cloud.tosca.catalog.index.IToscaTypeSearchService;
import org.alien4cloud.tosca.model.templates.Topology;
import org.alien4cloud.tosca.model.types.AbstractToscaType;
import org.alien4cloud.tosca.model.types.NodeType;
import org.alien4cloud.tosca.topology.TopologyDTOBuilder;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.inject.Inject;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import static alien4cloud.dao.FilterUtil.fromKeyValueCouples;

/**
 * Service that allows managing applications.
 */
@Slf4j
@RestController
//@ConfigurationProperties(prefix = "wizard.overview")
@RequestMapping({"/rest/wizard", "/rest/v1/wizard", "/rest/latest/wizard"})
@Api(value = "", description = "Operations on Applications")
public class ApplicationWizardController {

    @Resource
    private ApplicationWizardConfiguration applicationWizardConfiguration;

    @Resource
    private IImageDAO imageDAO;
    @Resource(name = "alien-es-dao")
    private IGenericSearchDAO alienDAO;
    @Resource
    ArchiveIndexer archiveIndexer;
    @Resource
    private ApplicationService applicationService;
    @Resource
    private ApplicationVersionService applicationVersionService;
    @Resource
    private ApplicationEnvironmentService applicationEnvironmentService;
    @Resource
    private TopologyService topologyService;
    @Resource
    private TopologyServiceCore topologyServiceCore;
    @Resource(name = "alien-es-dao")
    private IGenericSearchDAO dao;
    @Inject
    private TopologyDTOBuilder topologyDTOBuilder;
    @Resource
    private IToscaTypeSearchService toscaTypeSearchService;

    private static final Pattern NUMBER_DETECTION_PATTERN = Pattern.compile("(.*\\D+)(\\d+)");

    @RequestMapping(value = "/applications/suggestion/{applicationName:.+}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @PreAuthorize("isAuthenticated()")
    public RestResponse<String> getSuggestedName(@PathVariable String applicationName) {
        String generatedName = generateUniqueApplicationName(applicationName);
        return RestResponseBuilder.<String> builder().data(generatedName).build();
    }

    private String generateUniqueApplicationName(String suggestedName) {
        try {
            applicationService.checkApplicationName(suggestedName);
            return suggestedName;
        } catch(AlreadyExistException e) {
            log.debug("Application name already used: " + suggestedName);
        }

        String generatedName = suggestedName;
        Matcher m = NUMBER_DETECTION_PATTERN.matcher(suggestedName);
        if (m.matches()) {
            String prefixeName = m.group(1);
            Integer suffixeNumber = Integer.parseInt(m.group(2));
            generatedName = prefixeName + (++suffixeNumber);
        } else {
            generatedName += "2";
        }

        return generateUniqueApplicationName(generatedName);
    }

        /**
         * Get an application from it's id.
         *
         * @param applicationId The application id.
         */
    @ApiOperation(value = "Get an application based from its id.", notes = "Returns the application details. Application role required [ APPLICATION_MANAGER | APPLICATION_USER | APPLICATION_DEVOPS | DEPLOYMENT_MANAGER ]")
    @RequestMapping(value = "/applications/overview/{applicationId:.+}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @PreAuthorize("isAuthenticated()")
    public RestResponse<ApplicationOverview> get(@PathVariable String applicationId) {
        Application application = applicationService.checkAndGetApplication(applicationId);
        ApplicationOverview overview = new ApplicationOverview();
        overview.setComponentCategories(applicationWizardConfiguration.getComponentCategories());

        overview.setNamedMetaProperties(getNamedMetaProperties(application.getMetaProperties(), applicationWizardConfiguration.getApplicationOverviewMetapropertiesSet()));

        ApplicationEnvironment applicationEnvironment = applicationEnvironmentService.getEnvironmentByIdOrDefault(applicationId, null);
        overview.setApplicationEnvironment(applicationEnvironment);
        DeploymentStatus status = null;
        try {
            overview.setDeploymentStatus(applicationEnvironmentService.getStatus(applicationEnvironment));
        } catch (Exception e) {
            overview.setDeploymentStatus(DeploymentStatus.UNKNOWN);
        }

        overview.setDescription(application.getDescription());
        overview.setApplication(application);
<commit_msg>[ALIEN-3175] add backend endpoint to retrieve application overview for a given environment<commit_after>package alien4cloud.rest.wizard;

import alien4cloud.application.ApplicationEnvironmentService;
import alien4cloud.application.ApplicationService;
import alien4cloud.application.ApplicationVersionService;
import alien4cloud.dao.IGenericSearchDAO;
import alien4cloud.dao.model.FacetedSearchResult;
import alien4cloud.exception.AlreadyExistException;
import alien4cloud.images.IImageDAO;
import alien4cloud.model.application.Application;
import alien4cloud.model.application.ApplicationEnvironment;
import alien4cloud.model.common.MetaPropConfiguration;
import alien4cloud.paas.model.DeploymentStatus;
import alien4cloud.rest.component.ComponentSearchRequest;
import alien4cloud.rest.model.*;
import alien4cloud.rest.wizard.model.*;
import alien4cloud.topology.TopologyDTO;
import alien4cloud.topology.TopologyService;
import alien4cloud.topology.TopologyServiceCore;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.alien4cloud.tosca.catalog.index.ArchiveIndexer;
import org.alien4cloud.tosca.catalog.index.IToscaTypeSearchService;
import org.alien4cloud.tosca.model.templates.Topology;
import org.alien4cloud.tosca.model.types.AbstractToscaType;
import org.alien4cloud.tosca.model.types.NodeType;
import org.alien4cloud.tosca.topology.TopologyDTOBuilder;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.inject.Inject;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import static alien4cloud.dao.FilterUtil.fromKeyValueCouples;

/**
 * Service that allows managing applications.
 */
@Slf4j
@RestController
//@ConfigurationProperties(prefix = "wizard.overview")
@RequestMapping({"/rest/wizard", "/rest/v1/wizard", "/rest/latest/wizard"})
@Api(value = "", description = "Operations on Applications")
public class ApplicationWizardController {

    @Resource
    private ApplicationWizardConfiguration applicationWizardConfiguration;

    @Resource
    private IImageDAO imageDAO;
    @Resource(name = "alien-es-dao")
    private IGenericSearchDAO alienDAO;
    @Resource
    ArchiveIndexer archiveIndexer;
    @Resource
    private ApplicationService applicationService;
    @Resource
    private ApplicationVersionService applicationVersionService;
    @Resource
    private ApplicationEnvironmentService applicationEnvironmentService;
    @Resource
    private TopologyService topologyService;
    @Resource
    private TopologyServiceCore topologyServiceCore;
    @Resource(name = "alien-es-dao")
    private IGenericSearchDAO dao;
    @Inject
    private TopologyDTOBuilder topologyDTOBuilder;
    @Resource
    private IToscaTypeSearchService toscaTypeSearchService;

    private static final Pattern NUMBER_DETECTION_PATTERN = Pattern.compile("(.*\\D+)(\\d+)");

    @RequestMapping(value = "/applications/suggestion/{applicationName:.+}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @PreAuthorize("isAuthenticated()")
    public RestResponse<String> getSuggestedName(@PathVariable String applicationName) {
        String generatedName = generateUniqueApplicationName(applicationName);
        return RestResponseBuilder.<String> builder().data(generatedName).build();
    }

    private String generateUniqueApplicationName(String suggestedName) {
        try {
            applicationService.checkApplicationName(suggestedName);
            return suggestedName;
        } catch(AlreadyExistException e) {
            log.debug("Application name already used: " + suggestedName);
        }

        String generatedName = suggestedName;
        Matcher m = NUMBER_DETECTION_PATTERN.matcher(suggestedName);
        if (m.matches()) {
            String prefixeName = m.group(1);
            Integer suffixeNumber = Integer.parseInt(m.group(2));
            generatedName = prefixeName + (++suffixeNumber);
        } else {
            generatedName += "2";
        }

        return generateUniqueApplicationName(generatedName);
    }

        /**
         * Get an application from it's id.
         *
         * @param applicationId The application id.
         */
    @ApiOperation(value = "Get an application based from its id.", notes = "Returns the application details. Application role required [ APPLICATION_MANAGER | APPLICATION_USER | APPLICATION_DEVOPS | DEPLOYMENT_MANAGER ]")
    @RequestMapping(value = "/applications/overview/{applicationId:.+}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @PreAuthorize("isAuthenticated()")
    public RestResponse<ApplicationOverview> get(@PathVariable String applicationId) {
        return _getApplicationEnvironmentOverview(applicationId, null);
    }

    /**
     * Get an application from it's id.
     *
     * @param applicationId The application id.
     */
    @ApiOperation(value = "Get an application based from its id.", notes = "Returns the application details. Application role required [ APPLICATION_MANAGER | APPLICATION_USER | APPLICATION_DEVOPS | DEPLOYMENT_MANAGER ]")
    @RequestMapping(value = "/applications/overview/{applicationId:.+}/{environmentId:.+}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @PreAuthorize("isAuthenticated()")
    public RestResponse<ApplicationOverview> getApplicationEnvironmentOverview(@PathVariable String applicationId, @PathVariable String environmentId) {
        return _getApplicationEnvironmentOverview(applicationId, environmentId);
    }

    private RestResponse<ApplicationOverview> _getApplicationEnvironmentOverview(String applicationId, String environmentId) {
        Application application = applicationService.checkAndGetApplication(applicationId);
        ApplicationOverview overview = new ApplicationOverview();
        overview.setComponentCategories(applicationWizardConfiguration.getComponentCategories());

        overview.setNamedMetaProperties(getNamedMetaProperties(application.getMetaProperties(), applicationWizardConfiguration.getApplicationOverviewMetapropertiesSet()));

        ApplicationEnvironment applicationEnvironment = applicationEnvironmentService.getEnvironmentByIdOrDefault(applicationId, environmentId);
        overview.setApplicationEnvironment(applicationEnvironment);
        DeploymentStatus status = null;
        try {
            overview.setDeploymentStatus(applicationEnvironmentService.getStatus(applicationEnvironment));
        } catch (Exception e) {
            overview.setDeploymentStatus(DeploymentStatus.UNKNOWN);
        }

        overview.setDescription(application.getDescription());
        overview.setApplication(application);

{'fraction_non_alphanumeric': 0.08849490184142444, 'fraction_numerical': 0.005174250494597474, 'mean_word_length': 4.841333333333333, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3145617', 'n_tokens_mistral': 3448, 'n_tokens_neox': 3362, 'n_words': 641}