/*
 * 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.isis.cli;

import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Deactivate;
import org.apache.karaf.shell.api.action.Argument;
import org.apache.karaf.shell.api.action.Command;
import org.onlab.packet.MacAddress;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.isis.controller.IsisController;
import org.onosproject.isis.controller.IsisInterface;
import org.onosproject.isis.controller.IsisLsdb;
import org.onosproject.isis.controller.IsisNeighbor;
import org.onosproject.isis.controller.IsisNetworkType;
import org.onosproject.isis.controller.IsisProcess;
import org.onosproject.isis.controller.IsisRouterType;
import org.onosproject.isis.controller.LspWrapper;
import org.onosproject.isis.io.isispacket.pdu.LsPdu;
import org.onosproject.isis.io.util.IsisConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.NetworkInterface;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Lists ISIS neighbors, database and interfaces details.
 */
@Service
@Command(scope = "onos", name = "isis", description = "lists database, neighbors and interfaces")
public class ApplicationIsisCommand extends AbstractShellCommand {
    private static final Logger log = LoggerFactory.getLogger(ApplicationIsisCommand.class);
    private static final String INTERFACE = "interface";
    private static final String DATABASE = "database";
    private static final String NEIGHBOR = "neighbor";
    private static final String P2P = "P2P";
    private static final String LAN = "LAN";
    private static final String L1 = "L1";
    private static final String L2 = "L2";
    private static final String L1L2 = "L1L2";
    protected IsisController isisController;
    @Argument(index = 0, name = "name",
            description = "interface|database|neighbor",
            required = true, multiValued = false)
    String name = null;
    @Argument(index = 1, name = "processId",
            description = "processId", required = true, multiValued = false)
    String processId = null;

    @Activate
    public void activate() {
        log.debug("Activated...!!!");
    }

    @Deactivate
    public void deactivate() {
        log.debug("Deactivated...!!!");
    }

    @Override
    protected void doExecute() {
        switch (name) {
            case INTERFACE:
                displayIsisInterfaces();
                break;
            case NEIGHBOR:
                displayIsisNeighbors();
                break;
            case DATABASE:
                displayIsisDatabase();
                break;
            default:
                log.debug("Unknown command...!!");
                break;
        }
    }

    /**
     * Displays ISIS neighbor details.
     */
    private void displayIsisNeighbors() {
        String interfaceName = "";
        String circuitType = "";
        boolean invalidProcess = true;
        try {
            this.isisController = get(IsisController.class);
            List<IsisProcess> listOfProcess = isisController.allConfiguredProcesses();
            if (listOfProcess == null) {
                return;
            }
            displayNeighborHeader();
            Iterator<IsisProcess> itrProcess = listOfProcess.iterator();
            while (itrProcess.hasNext()) {
                IsisProcess isisProcess = itrProcess.next();
                if (processId != null && processId.trim().equals(isisProcess.processId())) {
                    invalidProcess = false;
                    List<IsisInterface> interfaceList = isisProcess.isisInterfaceList();
                    Iterator<IsisInterface> itrInterface = interfaceList.iterator();
                    while (itrInterface.hasNext()) {
                        IsisInterface isisInterface = itrInterface.next();
                        interfaceName = NetworkInterface.getByIndex(isisInterface.interfaceIndex()).getName();
                        Set<MacAddress> getNeighborList = isisInterface.neighbors();
                        for (MacAddress mac : getNeighborList) {
                            IsisNeighbor neighbor = isisInterface.lookup(mac);
                            switch (neighbor.routerType()) {
                                case L1:
                                    circuitType = L1;
                                    break;
                                case L2:
                                    circuitType = L2;
                                    break;
                                case L1L2:
                                    circuitType = L1L2;
                                    break;
                                default:
                                    log.debug("Unknown circuit type...!!");
                                    break;
                            }
                            print("%-20s%-20s%-20s%-20s%-20s%-20s\n", neighbor.neighborSystemId(),
                                  neighbor.neighborMacAddress().toString(), interfaceName,
                                  circuitType, neighbor.interfaceState(), neighbor.holdingTime());
                        }
                    }
                }
            }
            if (invalidProcess) {
                print("%s\n", "Process " + processId + " not exist...!!!");
            }
        } catch (Exception e) {
            log.debug("Error occurred while displaying ISIS neighbor: {}", e.getMessage());
        }
    }

    /**
     * Displays ISIS database details.
     */
    private void displayIsisDatabase() {
        try {
            this.isisController = get(IsisController.class);
            List<IsisProcess> listOfProcess = isisController.allConfiguredProcesses();
            Iterator<IsisProcess> itrProcess = listOfProcess.iterator();
            boolean invalidProcess = true;
            while (itrProcess.hasNext()) {
                IsisProcess isisProcess = itrProcess.next();
                if (processId != null && processId.trim().equals(isisProcess.processId())) {
                    invalidProcess = false;
                    List<IsisInterface> interfaceList = isisProcess.isisInterfaceList();
                    Iterator<IsisInterface> itrInterface = interfaceList.iterator();
                    if (itrInterface.hasNext()) {
                        IsisInterface isisInterface = itrInterface.next();
                        IsisLsdb isisLsdb = isisInterface.isisLsdb();
                        if (isisLsdb != null) {
                            Map<String, LspWrapper> lsWrapperListL1 = isisLsdb.getL1Db();
                            Map<String, LspWrapper> lsWrapperListL2 = isisLsdb.getL2Db();
                            Set<String> l1Wrapper = lsWrapperListL1.keySet();
                            Set<String> l2Wrapper = lsWrapperListL2.keySet();
                            if (l1Wrapper.size() > 0) {
                                print("IS-IS Level-1 link-state database:");
                                displayDatabaseHeader();
                                for (String string : l1Wrapper) {
                                    LspWrapper lspWrapper = lsWrapperListL1.get(string);
                                    LsPdu lsPdu = (LsPdu) lspWrapper.lsPdu();
                                    print("%-25s%-25s%-25s%-25s%-25s\n", lsPdu.lspId(), lsPdu.pduLength(),
                                          lsPdu.sequenceNumber(),
                                          Integer.toHexString(lsPdu.checkSum()), lspWrapper.remainingLifetime());
                                }
                            }
                            if (l2Wrapper.size() > 0) {
                                print("IS-IS Level-2 link-state database:");
                                displayDatabaseHeader();
                                for (String string2 : l2Wrapper) {
                                    LspWrapper lspWrapper2 = lsWrapperListL2.get(string2);
                                    LsPdu lsPdu2 = (LsPdu) lspWrapper2.lsPdu();
                                    print("%-25s%-25s%-25s%-25s%-25s\n", lsPdu2.lspId(), lsPdu2.pduLength(),
                                          lsPdu2.sequenceNumber(), Integer.toHexString(lsPdu2.checkSum()),
                                          IsisConstants.LSPMAXAGE - lspWrapper2.currentAge());
                                }
                            }
                            break;
                        }
                    }
                }
            }
            if (invalidProcess) {
                print("%s\n", "Process " + processId + " not exist...!!!");
            }
        } catch (Exception e) {
            log.debug("Error occurred while displaying ISIS database: {}", e.getMessage());
        }
    }

    /**
     * Displays ISIS interfaces.
     */
    private void displayIsisInterfaces() {
        String interfaceName = "";
        String networkType = "";
        String circuitType = "";
        boolean invalidProcess = true;
        try {
            this.isisController = get(IsisController.class);
            List<IsisProcess> listOfProcess = isisController.allConfiguredProcesses();
            if (listOfProcess == null) {
                return;
            }
            displayInterfaceHeader();
            Iterator<IsisProcess> itrProcess = listOfProcess.iterator();
            while (itrProcess.hasNext()) {
                IsisProcess isisProcess = itrProcess.next();
                if (processId != null && processId.trim().equals(isisProcess.processId())) {
                    invalidProcess = false;
                    List<IsisInterface> interfaceList = isisProcess.isisInterfaceList();
                    for (IsisInterface isisInterface : interfaceList) {

                        if (isisInterface.networkType() == IsisNetworkType.P2P) {
                            networkType = P2P;
                        } else {
                            networkType = LAN;
                        }

                        switch (IsisRouterType.get(isisInterface.reservedPacketCircuitType())) {
                            case L1:
                                circuitType = L1;
                                break;
                            case L2:
                                circuitType = L2;
                                break;
                            case L1L2:
                                circuitType = L1L2;
                                break;
                            default:
                                log.debug("Unknown circuit type...!!");
                                break;
                        }
                        interfaceName = NetworkInterface.getByIndex(isisInterface.interfaceIndex()).getName();
                        print("%-20s%-20s%-20s%-20s\n", interfaceName, isisInterface.areaAddress(),
                              networkType, circuitType);
                    }
                }
            }
            if (invalidProcess) {
                print("%s\n", "Process " + processId + " not exist...!!!");
            }
        } catch (Exception e) {
            log.debug("Error occurred while displaying ISIS interface: {}", e.getMessage());
        }
    }

    /**
     * Displays ISIS interface header.
     */
    private void displayInterfaceHeader() {
        print("%-20s%-20s%-20s%-20s\n", "Interface", "Area Id", "TYPE", "Level");
    }

    /**
     * Displays ISIS neighbor header.
     */
    private void displayNeighborHeader() {
        print("%-20s%-20s%-20s%-20s%-20s%-20s\n", "System Id", "Mac Id", "Interface",
              "Level", "State", "Holding Time");
    }

    /**
     * Displays ISIS database header.
     */
    private void displayDatabaseHeader() {
        print("%-25s%-25s%-25s%-25s%-25s\n", "LSP ID ", "PduLen", "SeqNumber", "Checksum",
              "Remaining Life Time");
    }
}
