/*-
 * ============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.common.dto.AccessPodDTO;
import org.onap.osam.common.dto.ChassisDTO;
import org.onap.osam.common.dto.OLTChassisDTO;
import org.onap.osam.common.dto.OLTPortDTO;
import org.onap.osam.common.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().name());
        oltPortDTO.setPortAuthState(oltPort.getPortAuthState().name());
        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;
    }
}
