/*
 * Copyright 2016-present Open Networking Foundation
 *
 * 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.
 */
package org.onosproject.pcep.cli;


import org.apache.karaf.shell.api.action.Argument;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.pcep.server.PcepClientController;
import org.onosproject.pcep.server.PcepErrorDetail;
import org.onosproject.pcep.server.PcepErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Set;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.TreeMap;

@Service
@Command(scope = "onos", name = "pcep", description = "Pcep Session Info")
public class PcepSessionCommand extends AbstractShellCommand {
    private static final Logger log = LoggerFactory.getLogger(PcepSessionCommand.class);
    private static final String SESSION = "session";
    private static final String EXCEPTION = "exception";
    private static final String ERROR = "error";
    private PcepClientController pcepClientController;
    private byte sessionId;
    private Set<String> pcepSessionKeySet;
    private Set<String> pcepSessionIdKeySet;
    private Integer sessionIdValue = 0;
    private String sessionStatus;
    private List pcepSessionExceptions = new ArrayList();
    private Set<String> pcepSessionFailurekeySet;
    private PcepErrorDetail pcepErrorDetail;
    private PcepErrorType pcepErrorType;
    private Map<Integer, String> sessionEstablishmentFailureMap = new TreeMap<>();
    private Map<Integer, String> unknownObjectMap = new TreeMap<>();
    private Map<Integer, String> notSupportedObjectMap = new TreeMap<>();
    private Map<Integer, String> policyViolationMap = new TreeMap<>();
    private Map<Integer, String> mandatoryObjectMissingMap = new TreeMap<>();
    private Map<Integer, String> receptionOfInvalidObjectMap = new TreeMap<>();
    private Map<Integer, String> invalidOperationMap = new TreeMap<>();
    private Set<Integer> pcepErrorMsgKey;
    private Integer pcepErrorValue = 0;

    @Argument(index = 0, name = "name",
            description = "session" + "\n" + "exception" + "\n" + "error",
            required = true, multiValued = false)
    String name = null;
    @Argument(index = 1, name = "peer",
            description = "peerIp",
            required = false, multiValued = false)
    String peer = null;

    @Override
    protected void doExecute() {
        switch (name) {
            case SESSION:
                displayPcepSession();
                break;
            case EXCEPTION:
                displayPcepSessionFailureReason();
                break;
            case ERROR:
                displayPcepErrorMsgs();
                break;
            default:
                System.out.print("Unknown Command");
                break;
        }
    }

    private void displayPcepSession() {
        try {
            this.pcepClientController = get(PcepClientController.class);
            Map<String, String> pcepSessionMap = pcepClientController.getPcepSessionMap();
            Map<String, Byte> pcepSessionIdMap = pcepClientController.getPcepSessionIdMap();
            pcepSessionKeySet = pcepSessionMap.keySet();
            pcepSessionIdKeySet = pcepSessionIdMap.keySet();
            if (peer != null) {
                if (!pcepSessionKeySet.isEmpty()) {
                    if (pcepSessionKeySet.contains(peer)) {
                        for (String pcepSessionPeer : pcepSessionKeySet) {
                            if (pcepSessionPeer.equals(peer)) {
                                for (String pcepSessionId : pcepSessionIdKeySet) {
                                    if (pcepSessionId.equals(peer)) {
                                        sessionId = pcepSessionIdMap.get(pcepSessionId);
                                        sessionStatus = pcepSessionMap.get(pcepSessionPeer);
                                        if (sessionId < 0) {
                                            sessionIdValue = sessionId + 256;
                                        } else {
                                            sessionIdValue = (int) sessionId;
                                        }
                                    }
                                }
                  print("SessionIp = %s, Status = %s, sessionId = %s", pcepSessionPeer, sessionStatus, sessionIdValue);
                            }
                        }
                    } else {
                        System.out.print("Wrong Peer IP");
                    }
                }
            } else {
                if (!pcepSessionKeySet.isEmpty()) {
                    for (String pcepSessionPeer : pcepSessionKeySet) {
                        for (String pcepSessionId : pcepSessionIdKeySet) {
                            if (pcepSessionId.equals(pcepSessionPeer)) {
                                sessionId = pcepSessionIdMap.get(pcepSessionId);
                                sessionStatus = pcepSessionMap.get(pcepSessionPeer);
                                if (sessionId < 0) {
                                    sessionIdValue = sessionId + 256;
                                } else {
                                    sessionIdValue = (int) sessionId;
                                }
                            }
                        }
                print("SessionIp = %s, Status = %s, sessionId = %s", pcepSessionPeer, sessionStatus, sessionIdValue);
                    }
                }
            }
        } catch (Exception e) {
            log.debug("Error occurred while displaying PCEP session information: {}", e.getMessage());
        }
    }

    private void displayPcepSessionFailureReason() {
        try {
            this.pcepClientController = get(PcepClientController.class);
            Map<String, List<String>> pcepSessionFailureReasonMap = pcepClientController.getPcepExceptions();
            pcepSessionFailurekeySet = pcepSessionFailureReasonMap.keySet();
            if (!pcepSessionFailurekeySet.isEmpty()) {
                if (peer != null) {
                    if (pcepSessionFailurekeySet.contains(peer)) {
                        for (String pcepSessionPeerId : pcepSessionFailurekeySet) {
                            if (pcepSessionPeerId.equals(peer)) {
                                pcepSessionExceptions = pcepSessionFailureReasonMap.get(pcepSessionPeerId);
                                print("PeerId = %s, FailureReason = %s", pcepSessionPeerId, pcepSessionExceptions);
                            }
                        }
                    } else {
                        System.out.print("Wrong Peer IP");
                    }

                } else {
                    pcepSessionFailurekeySet = pcepSessionFailureReasonMap.keySet();
                    if (!pcepSessionFailurekeySet.isEmpty()) {
                        for (String pcepSessionPeerId : pcepSessionFailurekeySet) {
                            pcepSessionExceptions = pcepSessionFailureReasonMap.get(pcepSessionPeerId);
                            print("PeerId = %s, FailureReason = %s", pcepSessionPeerId, pcepSessionExceptions);
                        }
                    }
                }

            }


        } catch (Exception e) {
            log.debug("Error occurred while displaying PCEP session failure reasons: {}", e.getMessage());
        }

    }


    private void displayPcepErrorMsgs() {
        try {
            this.pcepClientController = get(PcepClientController.class);
            Map<Integer, Integer> pcepErrorMsgMap = pcepClientController.getPcepErrorMsg();
            pcepErrorMsgKey = pcepErrorMsgMap.keySet();
            if (!pcepErrorMsgKey.isEmpty()) {
                for (Integer errorType : pcepErrorMsgKey) {
                    pcepErrorValue = pcepErrorMsgMap.get(errorType);
                    pcepErrorType = PcepErrorType.values()[errorType];
                    switch (pcepErrorType) {
                        case SESSIONESTABLISHMENTFAILURE:
                            sessionEstablishmentFailureMap =  pcepErrorDetail.sessionEstablishmentFailure();
                            Set<Integer> sessionFailureKeySet = sessionEstablishmentFailureMap.keySet();
                            for (Integer sessionFailureKey : sessionFailureKeySet) {
                                if (sessionFailureKey.equals(pcepErrorValue)) {
                                    System.out.print(sessionEstablishmentFailureMap.get(sessionFailureKey));
                                }
                            }
                            break;
                        case CAPABALITYNOTSUPPORTED:
                            System.out.print("Capability not supported");
                            break;
                        case UNKNOWNOBJECT:
                            unknownObjectMap =  pcepErrorDetail.unknownObject();
                            Set<Integer> unknownObjectKeySet = unknownObjectMap.keySet();
                            for (Integer unknownObjectKey : unknownObjectKeySet) {
                                if (unknownObjectKey.equals(pcepErrorValue)) {
                                    System.out.print(unknownObjectMap.get(unknownObjectKey));
                                }
                            }
                            break;
                        case NOTSUPPORTEDOBJECT:
                            notSupportedObjectMap =  pcepErrorDetail.notSupportedObject();
                            Set<Integer> notSupportedObjectKeySet = notSupportedObjectMap.keySet();
                            for (Integer notSupportedObjectKey : notSupportedObjectKeySet) {
                                if (notSupportedObjectKey.equals(pcepErrorValue)) {
                                    System.out.print(notSupportedObjectMap.get(notSupportedObjectKey));
                                }
                            }
                            break;
                        case POLICYVIOLATION:
                            policyViolationMap =  pcepErrorDetail.policyViolation();
                            Set<Integer> policyViolationKeySet = policyViolationMap.keySet();
                            for (Integer policyViolationKey : policyViolationKeySet) {
                                if (policyViolationKey.equals(pcepErrorValue)) {
                                    System.out.print(policyViolationMap.get(policyViolationKey));
                                }
                            }
                            break;
                        case MANDATORYOBJECTMISSING:
                            mandatoryObjectMissingMap =  pcepErrorDetail.mandatoryObjectMissing();
                            Set<Integer> mandatoryObjectMissingKeySet = mandatoryObjectMissingMap.keySet();
                            for (Integer mandatoryObjectMissingKey : mandatoryObjectMissingKeySet) {
                                if (mandatoryObjectMissingKey.equals(pcepErrorValue)) {
                                    System.out.print(mandatoryObjectMissingMap.get(mandatoryObjectMissingKey));
                                }
                            }
                            break;
                        case SYNCHRONIZEDPATHCOMPUTATIONREQUESTMISSING:
                            System.out.print("Synchronized path computation request missing");
                            break;
                        case UNKNOWNREQUESTREFERENCE:
                            System.out.print("Unknown request reference");
                            break;
                        case ESTABLISHINGSECONDPCEPSESSION:
                            System.out.print("Attempt to establish a second PCEP session");
                            break;
                        case RECEPTIONOFINVALIDOBJECT:
                            receptionOfInvalidObjectMap =  pcepErrorDetail.receptionOfInvalidObject();
                            Set<Integer> receptionOfInvalidObjectKeySet = receptionOfInvalidObjectMap.keySet();
                            for (Integer receptionOfInvalidObjectKey : receptionOfInvalidObjectKeySet) {
                                if (receptionOfInvalidObjectKey.equals(pcepErrorValue)) {
                                    System.out.print(receptionOfInvalidObjectMap.get(receptionOfInvalidObjectKey));
                                }
                            }
                            break;
                        case INVALIDOPERATION:
                            invalidOperationMap =  pcepErrorDetail.invalidOperation();
                            Set<Integer> invalidOperationKeySet = invalidOperationMap.keySet();
                            for (Integer invalidOperationKey : invalidOperationKeySet) {
                                if (invalidOperationKey.equals(pcepErrorValue)) {
                                    System.out.print(invalidOperationMap.get(invalidOperationKey));
                                }
                            }
                            break;
                        case VIRTUALNETWORKTLVMISSING:
                            System.out.print("VIRTUAL-NETWORK TLV missing");
                            break;
                        default:
                            System.out.print("Unknown error message");
                            break;
                    }
                }
            }
        }  catch (Exception e) {
            log.debug("Error occurred while displaying PCEP error messages received: {}", e.getMessage());
        }
    }
}
