/*
* Copyright 2022-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 main

/*
import (
	"bufio"
	"fmt"
	"os"
	"regexp"
	"strconv"
	"strings"

	app "voltha-go-controller/internal/pkg/application"
	"voltha-go-controller/internal/pkg/of"
)

// ProcessAddSub to add sub info
func ProcessAddSub(tokens []string) {
	device := "OpenOLT100"
	port := uint32(100)
	cvlan := uint16(100)
	uvlan := uint16(4096)
	svlan := uint16(4096)
	for _, token := range tokens {
		s := strings.Split(token, "=")
		switch s[0] {
		case "device":
			device = s[1]
		case "port":
			res, _ := strconv.Atoi(s[1])
			port = uint32(res)
		case "cvlan":
			res, _ := strconv.Atoi(s[1])
			cvlan = uint16(res)
		case "uvlan":
			res, _ := strconv.Atoi(s[1])
			uvlan = uint16(res)
		case "svlan":
			res, _ := strconv.Atoi(s[1])
			svlan = uint16(res)
		}
	}
	portStr := "OFPort" + strconv.FormatInt(int64(port), 10)
	var vsc app.VoltServiceCfg
	vsc.UniVlan = of.VlanType(uvlan)
	vsc.CVlan = of.VlanType(cvlan)
	vsc.SVlan = of.VlanType(svlan)
	vsc.CircuitID = device + portStr
	vsc.RemoteID = []byte("test")
	vsc.Port = portStr
	vsc.Name = device + portStr + strconv.FormatInt(int64(cvlan), 10)

	app.GetApplication().AddService(vsc, nil)
}

// ProcessAddSubs to add multiple sub info
func ProcessAddSubs(tokens []string) {
	device := "OpenOLT100"
	cvlan := uint16(1015)
	uvlan := uint16(1015)
	svlan := uint16(2)
	//maclearning := false
	numSubs, _ := strconv.Atoi(tokens[0])
	for _, token := range tokens[1:] {
		s := strings.Split(token, "=")
		switch s[0] {
		case "device":
			device = s[1]
		case "cvlan":
			res, _ := strconv.Atoi(s[1])
			cvlan = uint16(res)
		case "uvlan":
			res, _ := strconv.Atoi(s[1])
			uvlan = uint16(res)
		case "svlan":
			res, _ := strconv.Atoi(s[1])
			svlan = uint16(res)
			// case "maclearning":
			// 	maclearning = true
		}
	}
	fmt.Println("Adding", numSubs, "Subscribers")
	for port := 1; port <= numSubs; port++ {
		for pbit := 0; pbit < 2; pbit++ {
			p := of.PbitType(pbit)
			portStr := "OFPort" + strconv.FormatInt(int64(port), 10)
			var vsc app.VoltServiceCfg
			vsc.UniVlan = of.VlanType(uvlan)
			vsc.CVlan = of.VlanType(cvlan)
			vsc.SVlan = of.VlanType(svlan)
			vsc.Pbits = []of.PbitType{p, p + 2, p + 4, p + 6}
			vsc.CircuitID = device + portStr
			// TODO : need to fix this only if its used.
			//vsc.MacLearning = maclearning
			vsc.RemoteID = []byte("test")
			vsc.Port = portStr
			vsc.Name = portStr + strconv.FormatInt(int64(cvlan), 10) + "PBIT" + strconv.FormatInt(int64(pbit), 10)

			if err := app.GetApplication().AddService(vsc, nil); err != nil {
				fmt.Println("Addition of sub with", port, "Pbit", pbit, "Failed - Reason", err.Error())
			}
		}
	}
}

// ProcessAddVnet to add vnet info
func ProcessAddVnet(tokens []string) {
	// Set the defaults so that each parameter doesn't need to be
	// configured each time
	cvlan := of.VlanType(1015)
	svlan := of.VlanType(2)
	uvlan := of.VlanType(1015)
	dhcprelay := false
	usdhcppbit := uint8(0)
	dsdhcppbit := uint8(6)

	// Read the attributes and set the values
	for _, token := range tokens[:] {
		s := strings.Split(token, "=")
		switch s[0] {
		case "dhcprelay":
			dhcprelay = true
		case "cvlan":
			res, _ := strconv.Atoi(s[1])
			cvlan = of.VlanType(res)
		case "uvlan":
			res, _ := strconv.Atoi(s[1])
			uvlan = of.VlanType(res)
		case "svlan":
			res, _ := strconv.Atoi(s[1])
			svlan = of.VlanType(res)
		case "usdhcppbit":
			res, _ := strconv.Atoi(s[1])
			usdhcppbit = uint8(res)
		case "dsdhcppbit":
			res, _ := strconv.Atoi(s[1])
			usdhcppbit = uint8(res)
		}
	}

	// Perform the configuration
	name := "NW" + strconv.FormatInt(int64(svlan), 10) + "-" + strconv.FormatInt(int64(cvlan), 10)
	cfg := app.VnetConfig{
		Name:      name,
		SVlan:     svlan,
		CVlan:     cvlan,
		UniVlan:   uvlan,
		DhcpRelay: dhcprelay,
	}
	cfg.UsDhcpPbit = append(cfg.UsDhcpPbit, of.PbitType(usdhcppbit))
	cfg.DsDhcpPbit = append(cfg.DsDhcpPbit, of.PbitType(dsdhcppbit))
	if err := app.GetApplication().AddVnet(cfg, nil); err != nil {
		fmt.Println("Error in configuration - Reason :", err.Error())
	}
}

// ProcessDelSubs to delete multiple sub info
func ProcessDelSubs(tokens []string) {
	cvlan := uint16(1015)
	numSubs, _ := strconv.Atoi(tokens[0])
	for _, token := range tokens[1:] {
		s := strings.Split(token, "=")
		switch s[0] {
		// 	case "device":
		// 		device = s[1]
		case "cvlan":
			res, _ := strconv.Atoi(s[1])
			cvlan = uint16(res)
			// 	case "uvlan":
			// 		res, _ := strconv.Atoi(s[1])
			// 		uvlan = uint16(res)
			// 	case "svlan":
			// 		res, _ := strconv.Atoi(s[1])
			// 		svlan = uint16(res)
			// 	case "maclearning":
			// 		maclearning = true
		}
	}
	fmt.Println("Deleting", numSubs, "Subscribers")
	for port := 1; port <= numSubs; port++ {
		for pbit := 0; pbit < 2; pbit++ {
			portStr := "OFPort" + strconv.FormatInt(int64(port), 10)
			name := portStr + strconv.FormatInt(int64(cvlan), 10) + "PBIT" + strconv.FormatInt(int64(pbit), 10)
			app.GetApplication().DelService(name, false, nil, false)
		}
	}
}

// ProcessCli to process cli
func ProcessCli() {
	scanner := bufio.NewScanner(os.Stdin)
	a := regexp.MustCompile(" +")
	for {
		fmt.Print("Controller> Enter Command:")
		scanner.Scan()
		command := scanner.Text()
		s := a.Split(command, -1)
		switch s[0] {
		case "addsub":
			ProcessAddSub(s[1:])
		case "addsubs":
			ProcessAddSubs(s[1:])
		case "delsubs":
			ProcessDelSubs(s[1:])
		case "addvnet":
			ProcessAddVnet(s[1:])
		case "exit":
			return
		case "":

		default:
			fmt.Println("Unknown Command")
		}
	}
}*/
