package com.bocloud.ims.repository.resource.hmc;

import com.bocloud.ims.entity.resource.hmc.HmdViosPhysicalEthernetAdapter;
import com.bocloud.ims.entity.resource.hmc.HmdViosSea;
import com.bocloud.ims.entity.resource.hmc.HmdVirtualNetworkAdapter;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Repository
public abstract class HmdViosSeaRepository extends HmdGenericDao<HmdViosSea> {

    @Lookup protected abstract HmdPartitionRepository partitionRepository();
    @Lookup protected abstract HmdVirtualNetworkAdapterRepository virtualNetworkAdapterRepository();
    @Lookup protected abstract HmdViosPhysicalEthernetAdapterRepository viosPhysicalEthernetAdapterRepository();


    public HmdViosSeaRepository(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate npJdbcTemplate) {
        super(jdbcTemplate, npJdbcTemplate);
    }

    @Override
    public void extra(HmdViosSea sea) {
        Optional.of(sea).map(HmdViosSea::getViosId).map(this.partitionRepository()::getById).ifPresent(sea::setVios);
    }

    public List<HmdViosSea> listByViosId(long viosId) {
        return this.search(Collections.singletonMap("a.vios_id", viosId));
    }

    public HmdViosSea getByUniqueDeviceId(String uniqueDeviceId) {
        return this.search(Collections.singletonMap("a.unique_device_id", uniqueDeviceId)).stream().findFirst().orElse(null);
    }

    public HmdViosSea getById(long id) {
        return this.search(Collections.singletonMap("a.id", id)).stream().findFirst().orElse(null);
    }

    @Override
    public void convertInstance(final HmdViosSea srcT, final HmdViosSea desT) {
        Optional<HmdViosPhysicalEthernetAdapter> physicalEthernetAdapter = Optional.of(srcT)
            .map(HmdViosSea::getPhysicalEthernetAdapter)
            .map(HmdViosPhysicalEthernetAdapter::getPhysicalLocation)
            .map(this.viosPhysicalEthernetAdapterRepository()::getByPhysicalLocation);
        physicalEthernetAdapter.map(HmdViosPhysicalEthernetAdapter::getId).ifPresent(srcT::setPhysicalEthernetAdapterId);
        physicalEthernetAdapter.ifPresent(srcT::setPhysicalEthernetAdapter);

        Optional.of(srcT).map(HmdViosSea::getViosId).ifPresent(viosId -> {
                Optional<HmdVirtualNetworkAdapter> virtualNetworkAdapter = Optional.of(srcT)
                    .map(HmdViosSea::getVirtualNetworkAdapter)
                    .map(HmdVirtualNetworkAdapter::getAdapterId)
                    .map(adapterId -> this.virtualNetworkAdapterRepository().getByPartitionAdapterId(viosId, adapterId));
                virtualNetworkAdapter.map(HmdVirtualNetworkAdapter::getId).ifPresent(srcT::setPartitionNetworkAdapterId);
                virtualNetworkAdapter.ifPresent(srcT::setVirtualNetworkAdapter);
            }
        );

        this.copy(srcT, desT);
    }

}
