/*-
 * ============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=========================================================
 */



/*
 * Copyright 2015, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *    * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *
 *    * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.onap.osam.external.grpc;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import lombok.extern.slf4j.Slf4j;
import org.onap.osam.common.exception.AbstractOLTException;
import org.onap.osam.common.exception.ServerException;
import org.onap.osam.grpc.AbstractOLTGrpc;
import org.onap.osam.grpc.AddChassisMessage;
import org.onap.osam.grpc.AddChassisReturn;
import org.onap.osam.grpc.AddOLTChassisMessage;
import org.onap.osam.grpc.AddOLTChassisReturn;
import org.onap.osam.grpc.AddOntFullMessage;
import org.onap.osam.grpc.AddOntMessage;
import org.onap.osam.grpc.AddOntReturn;
import org.onap.osam.grpc.PreProvisionOntMessage;
import org.onap.osam.model.dao.Chassis;
import org.onap.osam.model.dao.OLTSlot;
import org.onap.osam.model.dao.ONTDevice;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;

@Component
@PropertySource("classpath:abstractolt.properties")
@Slf4j
public class AbstractOLTClient {

  private static final String ABSTRACTOLT_HOST = "${abstractolt.host}";
  private static final String ABSTRACTOLT_PORT = "${abstractolt.port}";

  public static int NUMBER_OF_OLT_PORTS = 16;

  private AbstractOLTGrpc.AbstractOLTBlockingStub blockingStub;
  @Value(ABSTRACTOLT_HOST)
  private String host;
  @Value(ABSTRACTOLT_PORT)
  private int port;

  @PostConstruct
  private void init() {
      log.info("Abstract OLT connection properties - host: {}, port: {}", host, port);
      ManagedChannel managedChannel = ManagedChannelBuilder
                .forAddress(host, port).usePlaintext().build();

      blockingStub = AbstractOLTGrpc.newBlockingStub(managedChannel);
  }

  /** create chassis */
  public void createChassis(Chassis chassis) {
      try {
          log.info("createChassis begin, chassis: {}", chassis);

          String clli = chassis.getClli();
          int rack = chassis.getRack();
          int shelf = chassis.getShelf();
          String xosIP = chassis.getAccessPod().getCoreIp();
          int port = Integer.parseInt(chassis.getAccessPod().getCorePort());
          String user = chassis.getAccessPod().getUsername();
          String pass = chassis.getAccessPod().getPassword();

          AddChassisMessage request = AddChassisMessage.newBuilder()
                  .setCLLI(clli)
                  .setRack(rack)
                  .setShelf(shelf)
                  .setXOSIP(xosIP)
                  .setXOSPort(port)
                  .setXOSUser(user)
                  .setXOSPassword(pass)
                  .build();

          log.info("AddChassisMessage message: {}", request);

          AddChassisReturn response = blockingStub.createChassis(request);
          if (!StringUtils.isEmpty(response.getDeviceID())) {
              log.info("Chassis created in AbstractOLT with clli : {}", clli);
          } else {
              log.error("DeviceId of created chassis in AbstractOLT is empty or null, chassis: {}", chassis);
              throw new ServerException("DeviceId of created chassis in AbstractOLT is empty or null");
          }
      } catch (RuntimeException e){
          log.error("Chassis creation failed", e);
          throw new AbstractOLTException("Chassis creation failed for chassis : {}", chassis);
      }
  }

    public String createOLTChassis(OLTSlot olt) {

        String deviceID = null, chassisDeviceId = null;

        try {
            log.info("createOLTChassis begin, olt:{}", olt);

            String clli = olt.getChassis().getClli();
            AddOLTChassisMessage.OltDriver oltDriver =  AddOLTChassisMessage.OltDriver.forNumber((olt.getOltDriver().ordinal()));
            AddOLTChassisMessage.OltType oltType = AddOLTChassisMessage.OltType.forNumber((olt.getOltType().ordinal()));

            AddOLTChassisMessage request = AddOLTChassisMessage.newBuilder()
                    .setCLLI(clli)
                    .setDriver(oltDriver)
                    .setNumPorts(NUMBER_OF_OLT_PORTS)
                    .setSlotPort(olt.getPort())
                    .setSlotIP(olt.getIpAddress())
                    .setType(oltType)
                    .build();

            log.info("AddOLTChassisMessage message: {}", request);
            AddOLTChassisReturn response = blockingStub.createOLTChassis(request);
            deviceID = response.getDeviceID();
            chassisDeviceId = response.getChassisDeviceID();
            if(!StringUtils.isEmpty(response.getDeviceID()) && !StringUtils.isEmpty(response.getChassisDeviceID())) {
                log.info("OLT Chassis created in AbstractOLT deviceId : {} chassisDeviceId : {}",deviceID,chassisDeviceId);
            } else {
                log.error("Invalid return argument from AbstractOLT, deviceId : {} chassisDeviceId : {}",deviceID,chassisDeviceId);
                throw new ServerException("DeviceId of created chassis in AbstractOLT is empty or null");
            }

        } catch (RuntimeException e) {
            log.error("OLT Chassis creation failed", e);
            throw new AbstractOLTException("OLT Chassis creation failed for olt : {}", olt);
        }

        return deviceID;
    }

    public boolean preProvisionOnt(ONTDevice ontDevice) {

      boolean result = false;

        try {
            PreProvisionOntMessage preProvisionOntMessage = OntMessageFactory.getPreProvisionOntMessage(ontDevice);
            AddOntReturn response = blockingStub.preProvisionOnt(preProvisionOntMessage);
            result = response.getSuccess();
            log.info("preProvisionOnt with device id : {} success : {}" ,ontDevice.getSerialNumber(), result);
        } catch (RuntimeException e) {
            log.error("preProvisionOnt RPC failed", e);
            throw new AbstractOLTException("preProvisionOnt failed for ont : {}", ontDevice);
        }
      return result;
    }

    public boolean provisionONT(ONTDevice ontDevice) {

        boolean result = false;
        try {
            AddOntMessage request = OntMessageFactory.getOntMessage(ontDevice);
            AddOntReturn response = blockingStub.provisionOnt(request);
            result = response.getSuccess();
            log.info("provisionONT with device id : {} success : {}",ontDevice.getSerialNumber(), result);

        } catch (RuntimeException e) {
            log.error("provisionONT RPC failed", e);
            throw new AbstractOLTException("provisionONT failed for ont : {}", ontDevice);
        }

        return result;
    }

    public boolean provisionOntFull(ONTDevice ontDevice) {

        boolean result = false;

        try {
            AddOntFullMessage addOntFullMessage = OntMessageFactory.getOntFullMessage(ontDevice);
            AddOntReturn response = blockingStub.provisionOntFull(addOntFullMessage);
            result = response.getSuccess();
            log.info("provisionOntFull with device id : {} success : {}",ontDevice.getSerialNumber(), result);

        } catch (RuntimeException e) {
            log.error("provisionOntFull RPC failed", e);
            throw new AbstractOLTException("provisionOntFull failed for ont : {}", ontDevice);
        }

        return result;
    }

}
