/*-
 * ============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.core;

import org.onap.osam.external.aai.AaiClient;
import org.onap.osam.external.aai.model.PNF;
import org.onap.osam.model.dao.AccessPod;
import org.onap.osam.common.exception.NotFoundException;
import org.onap.osam.model.repository.AccessPodRepository;
import org.onap.osam.api.service.AccessPodService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

/**
 * Created by cemturker on 26.09.2018.
 */
@Service
public class AccessPodServiceImpl extends AbstractBaseServiceImpl implements AccessPodService {

    private AccessPodRepository accessPodRepository;

    private AaiClient aaiClient;

    @Autowired
    public AccessPodServiceImpl(AccessPodRepository accessPodRepository, AaiClient aaiClient) {
        this.accessPodRepository = accessPodRepository;
        this.aaiClient = aaiClient;
    }


    @Override
    public AccessPod addOrUpdate(AccessPod value) {
        PNF pnf = aaiClient.queryPnf(value.getPnfId());
        Optional<AccessPod> accessPodOptional = accessPodRepository.findByPnfId(pnf.getPnfId());
        if (accessPodOptional.isPresent()) {
            AccessPod tmp = accessPodOptional.get();
            value.setId(tmp.getId());
        }
        add(value,accessPodRepository);
        //TODO need to update connection to grpc!!
        return value;
    }

    @Override
    public void removeById(Long key) {
        remove(key,accessPodRepository,AccessPod.class);
    }

    @Override
    public AccessPod getById(Long key) {
        return get(key,accessPodRepository);
    }

    @Override
    public List<AccessPod> getAll() {
        return getAll(accessPodRepository);
    }

    @Override
    public AccessPod findByPnfId(String pnfId) {
        Optional<AccessPod> accessPodOp = accessPodRepository.findByPnfId(pnfId);
        if (!accessPodOp.isPresent()) {
            log.error("Access POD with pnfId : {} is not found", pnfId);
            throw new NotFoundException("Access POD with pnfId : {} is not found", pnfId);
        }
        return accessPodOp.get();
    }

    @Override
    public void removeByPnfId(String pnfId) {
        accessPodRepository.removeByPnfId(pnfId);
    }
}
