package swClient

import (
	"fmt"
	"log"
	"regexp"
	"strings"

	"github.rackspace.com/gorax/libs/switchlib/swModels"
)

// method to return all vlan in use on switch ports
func (s *Switch) VlansInUse(vlans []int) []int {
	if len(vlans) == 0 {
		return swModels.PortVlans(s.Config.IntConfig)
	}
	return swModels.VlansByPort(vlans, s.Config.IntConfig)

}

// method to return vlan names assoicated with a list of vlan numbers
func (s *Switch) VlanNames(vlans []int) map[int]string {
	vlanNames := make(map[int]string)
	for _, vlan := range vlans {
		vlanNames[vlan] = swModels.VlanName(vlan, s.Config.Vlans)
	}
	return vlanNames
}

func (s *Switch) PoByDesc(match string) *swModels.IntConfig {
	return swModels.PoByDesc(match, s.Config.IntConfig)
}

func (s *Switch) PoByInterfaceName(match string) *swModels.IntConfig {
	return swModels.PoByInterfaceName(match, s.Config.IntConfig)
}

func (s *Switch) VlanNameList(vlans []int) (vdata []*swModels.VlanConfig) {
	return swModels.VlanNameList(vlans, s.Config.Vlans)
}

func (s *Switch) MissingVlans(vlans []int) []int {
	return swModels.MissingVlans(vlans, s.Config.Vlans)
}

//func (s *Switch) PortConfig(port int) *swModels.IntConfig {
//	return swModels.portConfigByNumber(port, s.Config.IntConfig)
//}

func (s *Switch) PortConfig(portNum int) *swModels.IntConfig {
	name := ""
	if strings.Contains(s.Model, "2950G-") {
		name = fmt.Sprintf("GigabitEthernet0/%d", portNum)
	} else if regexp.MustCompile(`2950[T]?-`).MatchString(s.Model) {
		name = fmt.Sprintf("FastEthernet0/%d", portNum)
	} else if strings.Contains(s.Model, "2960G-") {
		name = fmt.Sprintf("GigabitEthernet0/%d", portNum)
	} else if strings.Contains(s.Model, "C2970G-") {
		name = fmt.Sprintf("GigabitEthernet0/%d", portNum)
	} else if regexp.MustCompile(`2960[SX]-`).MatchString(s.Model) {
		name = fmt.Sprintf("GigabitEthernet1/0/%d", portNum)
	} else if strings.Contains(s.Model, "2960-") {
		name = fmt.Sprintf("FastEthernet0/%d", portNum)
	} else if strings.Contains(s.Model, "3750-") {
		name = fmt.Sprintf("FastEthernet1/0/%d", portNum)
	} else if strings.Contains(s.Model, "3750G-") {
		name = fmt.Sprintf("GigabitEthernet1/0/%d", portNum)
	} else if strings.Contains(s.Model, "4948") {
		name = fmt.Sprintf("GigabitEthernet1/%d", portNum)
	} else if regexp.MustCompile(`N\dK`).MatchString(s.Model) {
		name = fmt.Sprintf("Ethernet1/%d", portNum)
	} else if regexp.MustCompile(`7050`).MatchString(s.Model) {
		name = fmt.Sprintf("Ethernet%d", portNum)
	} else {
		log.Printf("unmatched switch model: %s", s.Model)
	}

	if name == "" {
		return nil
	}

	for _, p := range s.Config.IntConfig {
		if p.Name == name {
			return p
		}
	}
	return nil
}

func (s *Switch) PortConfigByName(portName string) *swModels.IntConfig {
	for _, p := range s.Config.IntConfig {
		if strings.ToLower(p.Name) == strings.ToLower(portName) {
			return p
		}
	}
	return nil
}

func (s *Switch) VlanExist(vlan int) bool {
	return swModels.VlanExist(vlan, s.Config.Vlans)
}

func (s *SwConfig) VlanExist(vlan int) bool {
	return swModels.VlanExist(vlan, s.Vlans)
}

func (s *SwConfig) VlanName(vlan int) string {
	return swModels.VlanName(vlan, s.Vlans)
}

func (s *Switch) PortChannelConfig(po int) *swModels.IntConfig {
	return swModels.PortChannelConfByNum(&po, s.Config.IntConfig)
}

func (s *Switch) FindPortsByVlan(vlan int) []*swModels.IntConfig {
	return swModels.FindPortByVlan(vlan, s.Config.IntConfig)
}
