<%#
 Copyright 2013-2021 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

      https://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 %>.config;

import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
import org.assertj.core.util.Lists;
import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import org.springframework.data.couchbase.config.BeanNames;
import org.springframework.data.couchbase.config.CouchbaseConfigurer;
import org.testcontainers.couchbase.BucketDefinition;
import org.testcontainers.couchbase.CouchbaseContainer;

import java.util.List;

@Configuration
public class DatabaseConfigurationIT extends AbstractCouchbaseConfiguration {

    private CouchbaseProperties couchbaseProperties;

    private static CouchbaseContainer couchbaseContainer;

    private static CouchbaseEnvironment couchbaseEnvironment;

    private static CouchbaseCluster couchbaseCluster;

    public DatabaseConfigurationIT(CouchbaseProperties couchbaseProperties) {
        this.couchbaseProperties = couchbaseProperties;
    }

    @Override
    @Bean(destroyMethod = "", name = BeanNames.COUCHBASE_ENV)
    public CouchbaseEnvironment couchbaseEnvironment() {
        return getCouchbaseEnvironment();
    }

    @Override
    public Cluster couchbaseCluster() throws Exception {
        return getCouchbaseCluster();
    }

    @Override
    protected List<String> getBootstrapHosts() {
        return Lists.newArrayList(getCouchbaseContainer().getContainerIpAddress());
    }

    @Override
    protected String getBucketName() {
        return couchbaseProperties.getBucket().getName();
    }

    @Override
    protected String getBucketPassword() {
        return couchbaseProperties.getBucket().getPassword();
    }

    @Override
    protected CouchbaseConfigurer couchbaseConfigurer() {
        return this;
    }

    private CouchbaseContainer getCouchbaseContainer() {
        if (couchbaseContainer == null) {
            couchbaseContainer = new CouchbaseContainer("<%= DOCKER_COUCHBASE %>")
                .withBucket(new BucketDefinition(getBucketName()).withQuota(100))
                .withCredentials(getUsername(), getBucketPassword());
            couchbaseContainer.start();
        }
        return couchbaseContainer;
    }

    private CouchbaseEnvironment getCouchbaseEnvironment() {
         if (couchbaseEnvironment == null) {
             couchbaseEnvironment = DefaultCouchbaseEnvironment
                 .builder()
                 .bootstrapCarrierDirectPort(getCouchbaseContainer().getBootstrapCarrierDirectPort())
                 .bootstrapHttpDirectPort(getCouchbaseContainer().getBootstrapHttpDirectPort())
                 .build();
         }
         return couchbaseEnvironment;
    }

    private CouchbaseCluster getCouchbaseCluster() {
        if (couchbaseCluster == null) {
            couchbaseCluster = CouchbaseCluster.create(couchbaseEnvironment(),
                getCouchbaseContainer().getContainerIpAddress()
            );
        }
        return couchbaseCluster;
    }
}
