<%#
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you 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 <%= polygene.packageName %>.bootstrap.infrastructure;

import org.apache.polygene.api.common.Visibility;
import org.apache.polygene.api.identity.IdentityGenerator;
import org.apache.polygene.api.identity.UuidGeneratorMixin;
import org.apache.polygene.bootstrap.AssemblyException;
import org.apache.polygene.bootstrap.LayerAssembly;
import org.apache.polygene.bootstrap.ModuleAssembly;
import org.apache.polygene.bootstrap.layered.ModuleAssembler;
<%
if( polygene.entitystore !== 'Memory' && polygene.entitystore !== 'Preferences' && polygene.entitystore.indexOf('SQL') == -1 ) {
%>
import org.apache.polygene.entitystore.<%- polygene.entitystoremodule %>.<%- polygene.entitystore %>EntityStoreConfiguration;
<%
}
if( polygene.entitystore.indexOf('SQL') >= 0 ) {
%>
import org.apache.polygene.entitystore.sql.SQLEntityStoreConfiguration;
<%
}
%>
import org.apache.polygene.entitystore.<%- polygene.entitystoremodule %>.assembly.<%- polygene.entitystore %>EntityStoreAssembler;
<%
if( polygene.entitystore.indexOf('SQL') >= 0 ) {
%>import org.apache.polygene.library.sql.assembly.DataSourceAssembler;
import org.apache.polygene.library.sql.<%= polygene.dbpool.toLowerCase() %>.<%= polygene.dbpool %>DataSourceServiceAssembler;
<%
}
%>

public class <%- polygene.entitystore %>StorageModule
    implements ModuleAssembler
{
    public static final String NAME = "<%- polygene.entitystore %> Storage Module";
    private final ModuleAssembly configModule;

    <%- polygene.entitystore %>StorageModule( ModuleAssembly configModule )
    {
        this.configModule = configModule;
    }

    @Override
    public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module )
        throws AssemblyException
    {
<%
if( polygene.entitystore.indexOf( 'SQL' ) >= 0 ) {
%>        // DataSourceService
        new <%= polygene.dbpool %>DataSourceServiceAssembler()
            .identifiedBy( "<%= polygene.entitystore.toLowerCase() %>-datasource-service" )
            .visibleIn( Visibility.module )
            .withConfig( configModule, Visibility.application )
            .assemble( module );

        // DataSource
        new DataSourceAssembler()
            .withDataSourceServiceIdentity( "<%= polygene.entitystore.toLowerCase() %>-datasource-service" )
            .identifiedBy( "ds-es-<%= polygene.entitystore.toLowerCase() %>" )
            .visibleIn( Visibility.module )
            .withCircuitBreaker()
            .assemble( module );
<%
}
%>        new <%- polygene.entitystore %>EntityStoreAssembler()
            .visibleIn( Visibility.application  )
            .withConfig( configModule, Visibility.application )
            .identifiedBy( "es-<%- polygene.entitystore.toLowerCase() %>" )
            .assemble( module );
<%
if( polygene.entitystore === 'Cassandra' ) {
%>        configModule.forMixin( CassandraEntityStoreConfiguration.class );
<%
}
%>
        module.services( IdentityGenerator.class )
            .visibleIn( Visibility.application )
            .withMixins( UuidGeneratorMixin.class );
        return module;
    }
}