<%#
 Copyright 2013-2019 the original author or authors from the JHipster project.

 This file is part of the JHipster project, see https://www.jhipster.tech/
 for more information.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-%>
package <%= packageName %>.service<% if (service === 'serviceImpl') { %>.impl<% } %>;
<%  const serviceClassName = service === 'serviceImpl' ? entityClass + 'ServiceImpl' : entityClass + 'Service';
    let viaService = false;
    const instanceType = (dto === 'mapstruct') ? asDto(entityClass) : asEntity(entityClass);
    const instanceName = (dto === 'mapstruct') ? asDto(entityInstance) : asEntity(entityInstance);
    const mapper = entityInstance  + 'Mapper';
    const dtoToEntity = mapper + '.'+ 'toEntity';
    const entityToDto = 'toDto';
    const entityToDtoReference = mapper + '::'+ 'toDto';
    const repository = entityInstance  + 'Repository';
    const searchRepository = entityInstance  + 'SearchRepository';
    let isUsingMapsId = false;
    let mapsIdAssoc;
    for (idx in relationships) {
        isUsingMapsId = relationships[idx].useJPADerivedIdentifier;
        if ( isUsingMapsId === true) {
            mapsIdAssoc = relationships[idx];
            break;
        }
        isUsingMapsId = false;
    }
    if (service === 'serviceImpl') { %>
import <%= packageName %>.service.<%= entityClass %>Service;<% } %>
import <%= packageName %>.domain.<%= asEntity(entityClass) %>;
import <%= packageName %>.repository.<%= entityClass %>Repository;
<%_ if (isUsingMapsId === true) { _%>
import <%=packageName%>.repository.<%= mapsIdAssoc.otherEntityNameCapitalized %>Repository;
<%_ } _%>
<%_ if (reactiveRepositories) { _%>
import <%= packageName %>.repository.reactive.<%= entityClass %>ReactiveRepository;
<%_ } _%>
<%_ if (searchEngine === 'elasticsearch') { _%>
import <%= packageName %>.repository.search.<%= entityClass %>SearchRepository;
<%_ } _%>
<%_ if (dto === 'mapstruct') { _%>
import <%= packageName %>.service.dto.<%= asDto(entityClass) %>;
import <%= packageName %>.service.mapper.<%= entityClass %>Mapper;
<%_ } _%>
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

<%_ if (pagination !== 'no' || fieldsContainOwnerManyToMany === true) { _%>
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
<%_ } _%>
import org.springframework.stereotype.Service;
<%_ if (databaseType === 'sql') { _%>
import org.springframework.transaction.annotation.Transactional;
<%_ } _%>
<%_ if (reactiveRepositories) { _%>
import reactor.core.publisher.Flux;
<%_ } _%>

<%_ if (dto === 'mapstruct' && (pagination === 'no' ||  fieldsContainNoOwnerOneToOne === true)) { _%>
import java.util.LinkedList;
<%_ } _%>
<%_ if (pagination === 'no' ||  fieldsContainNoOwnerOneToOne === true) { _%>
import java.util.List;
<%_ } _%>
import java.util.Optional;
<%_ if (databaseType === 'cassandra') { _%>
import java.util.UUID;
<%_ } _%>
<%_ if (fieldsContainNoOwnerOneToOne === true || (pagination === 'no' && ((searchEngine === 'elasticsearch' && !viaService) || dto === 'mapstruct'))) { _%>
import java.util.stream.Collectors;
<%_ } _%>
<%_ if (fieldsContainNoOwnerOneToOne === true || (pagination === 'no' && searchEngine === 'elasticsearch' && !viaService)) { _%>
import java.util.stream.StreamSupport;
<%_ } _%>
<%_ if (searchEngine === 'elasticsearch') { _%>

import static org.elasticsearch.index.query.QueryBuilders.*;
<%_ } _%>

/**
 * Service Implementation for managing {@link <%= asEntity(entityClass) %>}.
 */
@Service<% if (databaseType === 'sql') { %>
@Transactional<% } %>
public class <%= serviceClassName %><% if (service === 'serviceImpl') { %> implements <%= entityClass %>Service<% } %> {

    private final Logger log = LoggerFactory.getLogger(<%= serviceClassName %>.class);
<%- include('../../common/inject_template', {asEntity, asDto, viaService: viaService, constructorName: serviceClassName, queryService: false, isUsingMapsId: isUsingMapsId, mapsIdAssoc: mapsIdAssoc, isController: false}); -%>

    /**
     * Save a <%= entityInstance %>.
     *
     * @param <%= instanceName %> the entity to save.
     * @return the persisted entity.
     */
    <%_ if (service === 'serviceImpl') { _%>
    @Override
    <%_ } _%>
    public <%= instanceType %> save(<%= instanceType %> <%= instanceName %>) {
        log.debug("Request to save <%= entityClass %> : {}", <%= instanceName %>);
<%- include('../../common/save_template', {asEntity, asDto, viaService: viaService, returnDirectly: true, isUsingMapsId: isUsingMapsId, mapsIdAssoc: mapsIdAssoc, isController: false}); -%>
    }

    /**
     * Get all the <%= entityInstancePlural %>.
     *<% if (pagination !== 'no') { %>
     * @param pageable the pagination information.<% } %>
     * @return the list of entities.
     */
    <%_ if (service === 'serviceImpl') { _%>
    @Override
    <%_ } _%>
    <%_ if (databaseType === 'sql') { _%>
    @Transactional(readOnly = true)
    <%_ } _%>
    public <% if (pagination !== 'no') { %>Page<<%= instanceType %><% } else { %>List<<%= instanceType %><% } %>> findAll(<% if (pagination !== 'no') { %>Pageable pageable<% } %>) {
        log.debug("Request to get all <%= entityClassPlural %>");
        <%_ if (pagination === 'no') { _%>
        return <%= entityInstance %>Repository.<% if (fieldsContainOwnerManyToMany === true) { %>findAllWithEagerRelationships<% } else { %>findAll<% } %>()<% if (dto === 'mapstruct') { %>.stream()
            .map(<%= entityToDtoReference %>)
            .collect(Collectors.toCollection(LinkedList::new))<% } %>;
        <%_ } else { _%>
        return <%= entityInstance %>Repository.findAll(pageable)<% if (dto !== 'mapstruct') { %>;<% } else { %>
            .map(<%= entityToDtoReference %>);<% } %>
        <%_ } _%>
    }
    <%_ if (reactiveRepositories) { _%>

    /**
     * Get all the <%= entityInstancePlural %>.
     * @return the {@link Flux} of entities.
     */
    public Flux<<%= instanceType %>> findAllAsFlux() {
        log.debug("Request to get all <%= entityClassPlural %> as a flux");
        return <%= entityInstance %>ReactiveRepository.findAll()<% if (dto === 'mapstruct') { %>
            .map(<%= entityToDtoReference %>)<% } %>;
    }
    <%_ } _%>
    <%_ if (fieldsContainOwnerManyToMany === true) { _%>

    /**
     * Get all the <%= entityInstancePlural %> with eager load of many-to-many relationships.
     *
     * @return the list of entities.
     */
    public Page<<%= instanceType %>> findAllWithEagerRelationships(Pageable pageable) {
        return <%= entityInstance %>Repository.findAllWithEagerRelationships(pageable)<% if (dto !== 'mapstruct') { %>;<% } else { %>.map(<%= entityToDtoReference %>);<% } %>
    }
    <% } %>
<%- include('../../common/get_filtered_template', {asEntity, asDto}); -%>
    /**
     * Get one <%= entityInstance %> by id.
     *
     * @param id the id of the entity.
     * @return the entity.
     */
    <%_ if (service === 'serviceImpl') { _%>
    @Override
    <%_ } _%>
    <%_ if (databaseType === 'sql') { _%>
    @Transactional(readOnly = true)
    <%_ } _%>
    public Optional<<%= instanceType %>> findOne(<%= pkType %> id) {
        log.debug("Request to get <%= entityClass %> : {}", id);<%- include('../../common/get_template', {asEntity, asDto, viaService, returnDirectly:true}); -%>
    }

    /**
     * Delete the <%= entityInstance %> by id.
     *
     * @param id the id of the entity.
     */
    <%_ if (service === 'serviceImpl') { _%>
    @Override
    <%_ } _%>
    public void delete(<%= pkType %> id) {
        log.debug("Request to delete <%= entityClass %> : {}", id);
<%- include('../../common/delete_template', {viaService: viaService}); -%>
    }
    <%_ if (searchEngine === 'elasticsearch') { _%>

    /**
     * Search for the <%= entityInstance %> corresponding to the query.
     *
     * @param query the query of the search.<% if (pagination !== 'no') { %>
     * @param pageable the pagination information.<% } %>
     * @return the list of entities.
     */
    <%_ if (service === 'serviceImpl') { _%>
    @Override
    <%_ } _%>
    <%_ if (databaseType === 'sql') { _%>
    @Transactional(readOnly = true)
    <%_ } _%>
    public <% if (pagination !== 'no') { %>Page<<%= instanceType %><% } else { %>List<<%= instanceType %><% } %>> search(String query<% if (pagination !== 'no') { %>, Pageable pageable<% } %>) {
        <%_ if (pagination === 'no') { _%>
        log.debug("Request to search <%= entityClassPlural %> for query {}", query);<%- include('../../common/search_stream_template', {viaService: viaService}); -%>
        <%_ } else { _%>
        log.debug("Request to search for a page of <%= entityClassPlural %> for query {}", query);
        return <%= entityInstance %>SearchRepository.search(queryStringQuery(query), pageable)<%_ if (dto !== 'mapstruct') { _%>;<% } else { %>
            .map(<%= entityToDtoReference %>);
        <%_ } } _%>
    }
    <%_ } _%>
}
