/*-
 * ============LICENSE_START=======================================================
 * OSAM Core
 * ================================================================================
 * Copyright (C) 2018 Netsia
 * ================================================================================
 * 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.
 * ============LICENSE_END=========================================================
 */



package org.onap.osam.helper;

import com.google.common.collect.Lists;
import org.onap.osam.dto.AccessPodDTO;
import org.onap.osam.dto.ChassisDTO;
import org.onap.osam.dto.OLTChassisDTO;
import org.onap.osam.dto.OLTPortDTO;
import org.onap.osam.dto.ONTDTO;
import org.onap.osam.model.dao.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


public final class DTOMapper {

    private DTOMapper () {

    }

    public static Chassis convertToChassis (ChassisDTO chassisDTO) {
        Chassis chassis = new Chassis();
        chassis.setClli(chassisDTO.getClli());
        chassis.setShelf(chassisDTO.getShelf());
        chassis.setRack(chassisDTO.getRack());
        chassis.setState(ActivityState.ACTIVE);
        AccessPod accessPod = new AccessPod();
        accessPod.setPnfId(chassisDTO.getPnfId());
        chassis.setAccessPod(accessPod);
        return chassis;
    }




    public static OLTSlot convertToOLT (OLTChassisDTO oltChassisDTO) {
        OLTSlot oltSlot = new OLTSlot();
        oltSlot.setIpAddress(oltChassisDTO.getIpAddress());
        oltSlot.setPort(oltChassisDTO.getPortNumber());
        oltSlot.setName(oltChassisDTO.getName());
        oltSlot.setOltDriver(OltDriver.valueOf(oltChassisDTO.getOltDriver()));
        oltSlot.setOltType(OltType.valueOf(oltChassisDTO.getOltType()));
        return oltSlot;
    }

    public static ChassisDTO convertChassisToDTO(Chassis chassis) {
        ChassisDTO chassisDTO = new ChassisDTO();
        chassisDTO.setId(chassis.getId());
        chassisDTO.setClli(chassis.getClli());
        chassisDTO.setRack(chassis.getRack());
        chassisDTO.setShelf(chassis.getShelf());
        chassisDTO.setPnfId(chassis.getAccessPod().getPnfId());
        return chassisDTO;
    }

    public static List<ChassisDTO> convertChassisToDTO(List<Chassis> chassises) {
        return chassises.stream().map(x -> convertChassisToDTO(x)).collect(Collectors.toList());
    }

    public static Map<String, List<OLTChassisDTO>> convertFromOLT(List<OLTSlot> oltSlots){
        return oltSlots.stream().map(x -> convertFromOLT(x)).collect(Collectors.toList()).stream().collect(Collectors.groupingBy(OLTChassisDTO::getClli));
    }

    public static OLTChassisDTO convertFromOLT (OLTSlot oltSlot) {
        OLTChassisDTO oltChassisDTO = new OLTChassisDTO();
        oltChassisDTO.setClli(oltSlot.getChassis().getClli());
        oltChassisDTO.setIpAddress(oltSlot.getIpAddress());
        oltChassisDTO.setName(oltSlot.getName());
        oltChassisDTO.setOltDriver(oltSlot.getOltDriver().name());
        oltChassisDTO.setOltType(oltSlot.getOltType().name());
        oltChassisDTO.setPortNumber(oltSlot.getPort());
        oltChassisDTO.setId(oltSlot.getId());
        return oltChassisDTO;
    }

    public static ONTDTO convertFromONTDevice (ONTDevice ontDevice) {
        ONTDTO ontdto = new ONTDTO();
        ontdto.setSerialNumber(ontDevice.getSerialNumber());
        ontdto.setPortNumber(ontDevice.getOLTPort().getPortNumber());
        ontdto.setId(ontDevice.getId());
        ontdto.setSlotNumber(ontDevice.getOLTPort().getOltSlot().getNumber());
        ontdto.setClli(ontDevice.getOLTPort().getOltSlot().getChassis().getClli());
        ontdto.setCtag(ontDevice.getCTag());
        ontdto.setStag(ontDevice.getSTag());
        ontdto.setCircuitId(ontDevice.getCircuitId());
        ontdto.setNasPortId(ontDevice.getNasPortId());
        if (ontDevice.getTechProfile() != null) {
            ontdto.setTechnologyProfile(ontDevice.getTechProfile().getName());
        }
        if (ontDevice.getSpeedProfile() != null) {
            ontdto.setSpeedProfile(ontDevice.getSpeedProfile().getName());
        }
        return ontdto;
    }

    public static ONTDevice convertToONTDevice (ONTDTO ontdto) {
        ONTDevice ontDevice = new ONTDevice();
        ontDevice.setNumber(ontdto.getOntNumber());
        ontDevice.setSerialNumber(ontdto.getSerialNumber());
        ontDevice.setCTag(ontdto.getCtag());
        ontDevice.setSTag(ontdto.getStag());
        ontDevice.setCircuitId(ontdto.getCircuitId());
        ontDevice.setNasPortId(ontdto.getNasPortId());
        TechnologyProfile technologyProfile = new TechnologyProfile();
        technologyProfile.setName(ontdto.getTechnologyProfile());
        ontDevice.setTechProfile(technologyProfile);
        SpeedProfile speedProfile = new SpeedProfile();
        speedProfile.setName(ontdto.getSpeedProfile());
        ontDevice.setSpeedProfile(speedProfile);
        Chassis chassis = new Chassis();
        chassis.setClli(ontdto.getClli());
        OLTSlot oltSlot = new OLTSlot();
        oltSlot.setChassis(chassis);
        OLTPort oltPort = new OLTPort();
        oltPort.setPortNumber(ontdto.getPortNumber());
        oltPort.setOltSlot(oltSlot);
        ontDevice.setOLTPort(oltPort);
        return ontDevice;
    }

    public static Map<String, List<ONTDTO>> convertFromONTDevice(List<ONTDevice> ontDevices){
        return ontDevices.stream().map(x -> convertFromONTDevice(x)).collect(Collectors.toList()).stream().collect(Collectors.groupingBy(ONTDTO::getClli));
    }

    public static AccessPod convertDtoToAccessPod(AccessPodDTO dto) {
        //TODO validate..
        AccessPod accessPod = new AccessPod();
        accessPod.setPnfId(dto.getPnfId());
        accessPod.setId(dto.getId());
        accessPod.setCoreIp(dto.getCoreIp());
        accessPod.setCorePort(dto.getCorePort());
        accessPod.setUsername(dto.getUsername());
        accessPod.setPassword(dto.getPassword());
        accessPod.setIp(dto.getIp());
        accessPod.setPort(dto.getPort());
        return accessPod;
    }

    public static AccessPodDTO convertAccessPodToDto(AccessPod accessPod) {
        //TODO validate..
        AccessPodDTO dto = new AccessPodDTO();
        dto.setPnfId(accessPod.getPnfId());
        dto.setCoreIp(accessPod.getCoreIp());
        dto.setCorePort(accessPod.getCorePort());
        dto.setUsername(accessPod.getUsername());
        dto.setPassword(accessPod.getPassword());
        dto.setIp(accessPod.getIp());
        dto.setId(accessPod.getId());
        dto.setPort(accessPod.getPort());
        return dto;
    }

    private static OLTPortDTO convertOLTPortToDTO(OLTPort oltPort) {
        OLTPortDTO oltPortDTO = new OLTPortDTO();
        oltPortDTO.setId(oltPort.getId());
        oltPortDTO.setAdminState(oltPort.getAdminState());
        oltPortDTO.setPortAuthState(oltPort.getPortAuthState());
        oltPortDTO.setPortNumber(oltPort.getPortNumber());
        return oltPortDTO;
    }

    public static List<AccessPodDTO> covertAccessPodsToDtos(List<AccessPod> accessPodList) {
        //TODO validate..
        List<AccessPodDTO> dtos = new ArrayList<>();
        for (AccessPod accessPod : accessPodList) {
            dtos.add(convertAccessPodToDto(accessPod));
        }
        return dtos;
    }

    public static AccessPodDTO representTheAccessPod(List<Chassis> chassisList, AccessPod accessPod) {
        if (accessPod == null) {
            return null;
        }
        AccessPodDTO accessPodDTO = convertAccessPodToDto(accessPod);
        if (chassisList == null || chassisList.isEmpty()) {
            return accessPodDTO;
        }
        List<ChassisDTO> chassisDTOS = new ArrayList<>();
        accessPodDTO.setChassises(chassisDTOS);
        for (Chassis chassis : chassisList) {
            chassisDTOS.add(representTheChassis(chassis));
        }
        return accessPodDTO;
    }

    public static ChassisDTO representTheChassis(Chassis chassis) {
        ChassisDTO chassisDTO = convertChassisToDTO(chassis);
        if (chassis.getOltSlots() == null || chassis.getOltSlots().isEmpty()) {
            return chassisDTO;
        }
        List<OLTChassisDTO> oltChassisDTOS = Lists.newArrayList();
        chassisDTO.setOlts(oltChassisDTOS);
        for (OLTSlot oltSlot : chassis.getOltSlots()) {
            oltChassisDTOS.add(representTheOLTSlot(oltSlot));
        }
        return chassisDTO;
    }

    public static OLTChassisDTO representTheOLTSlot(OLTSlot oltSlot) {
        OLTChassisDTO oltChassisDTO = convertFromOLT(oltSlot);
        if (oltSlot.getOltPorts() == null || oltSlot.getOltPorts().isEmpty()) {
            return oltChassisDTO;
        }
        List<OLTPortDTO> oltPortDTOS = Lists.newArrayList();
        oltChassisDTO.setOltPorts(oltPortDTOS);
        for (OLTPort oltPort : oltSlot.getOltPorts()) {
            oltPortDTOS.add(representTheOLTPort(oltPort));
        }
        return oltChassisDTO;
    }

    public static OLTPortDTO representTheOLTPort(OLTPort oltPort) {
        OLTPortDTO portDTO = convertOLTPortToDTO(oltPort);
        if (oltPort.getOntDevices() == null || oltPort.getOntDevices().isEmpty()) {
            return portDTO;
        }
        List<ONTDTO> ontdtos = Lists.newArrayList();
        portDTO.setOntDevices(ontdtos);
        for (ONTDevice ontDevice : oltPort.getOntDevices()) {
            ontdtos.add(convertFromONTDevice(ontDevice));
        }
        return portDTO;
    }
}
