package main

import (
	"context"
	"flag"
	"fmt"
	"reflect"
	"strconv"
	"strings"

	"code.hackerspace.pl/q3k/mirko"
	"github.com/golang/glog"
	"github.com/ziutek/telnet"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	pb "code.hackerspace.pl/q3k/m6220-proxy/proto"
	tpb "code.hackerspace.pl/q3k/topo/proto/control"
)

var (
	flagSwitchAddress  string
	flagSwitchUsername string
	flagSwitchPassword string
)

func init() {
	flag.Set("logtostderr", "true")
}

type service struct {
	connectionSemaphore chan int
}

func (s *service) connect() (*cliClient, error) {
	s.connectionSemaphore <- 1
	conn, err := telnet.Dial("tcp", flagSwitchAddress)
	if err != nil {
		<-s.connectionSemaphore
		return nil, err
	}

	cli := newCliClient(conn, flagSwitchUsername, flagSwitchPassword)
	return cli, nil
}

func (s *service) disconnect() {
	<-s.connectionSemaphore
}

func (s *service) RunCommand(ctx context.Context, req *pb.RunCommandRequest) (*pb.RunCommandResponse, error) {
	if req.Command == "" {
		return nil, status.Error(codes.InvalidArgument, "command cannot be null")
	}

	cli, err := s.connect()
	if err != nil {
		return nil, status.Error(codes.Unavailable, "could not connect to switch")
	}
	defer s.disconnect()

	lines, effective, err := cli.runCommand(ctx, req.Command)
	if err != nil {
		return nil, err
	}
	res := &pb.RunCommandResponse{
		EffectiveCommand: effective,
		Lines:            lines,
	}
	return res, nil
}

func (s *service) parseInterfaceStatus(res *tpb.GetPortsResponse, lines []string) error {
	if len(lines) < 4 {
		return fmt.Errorf("need at least 4 lines of output, got %d", len(lines))
	}
	if lines[0] != "" {
		return fmt.Errorf("expected first line to be empty, is %q", lines[0])
	}
	header1parts := strings.Fields(lines[1])
	if want := []string{"Port", "Description", "Duplex", "Speed", "Neg", "Link", "Flow", "Control"}; !reflect.DeepEqual(want, header1parts) {
		return fmt.Errorf("expected header1 to be %v, got %v", want, header1parts)
	}

	header2parts := strings.Fields(lines[2])
	if want := []string{"State", "Status"}; !reflect.DeepEqual(want, header2parts) {
		return fmt.Errorf("expected header2 to be %v, got %v", want, header2parts)
	}

	if lines[3][0] != '-' {
		return fmt.Errorf("expected header3 to start with -, got %q", lines[3])
	}

	for _, line := range lines[4:] {
		parts := strings.Fields(line)
		if len(parts) < 6 {
			break
		}
		portName := parts[0]
		if strings.HasPrefix(portName, "Gi") && strings.HasPrefix(portName, "Ti") {
			break
		}

		speedStr := parts[len(parts)-4]
		stateStr := parts[len(parts)-2]

		port := &tpb.SwitchPort{
			Name: portName,
		}
		if speedStr == "100" {
			port.Speed = tpb.SwitchPort_SPEED_100M
		} else if speedStr == "1000" {
			port.Speed = tpb.SwitchPort_SPEED_1G
		} else if speedStr == "10000" {
			port.Speed = tpb.SwitchPort_SPEED_10G
		}
		if stateStr == "Up" {
			port.LinkState = tpb.SwitchPort_LINKSTATE_UP
		} else if stateStr == "Down" {
			port.LinkState = tpb.SwitchPort_LINKSTATE_DOWN
		}

		res.Ports = append(res.Ports, port)
	}

	return nil
}

func (s *service) parseInterfaceConfig(port *tpb.SwitchPort, lines []string) error {
	glog.Infof("%+v", port)
	for _, line := range lines {
		glog.Infof("%s: %q", port.Name, line)
		parts := strings.Fields(line)
		if len(parts) < 1 {
			continue
		}

		if len(parts) >= 2 && parts[0] == "switchport" {
			if parts[1] == "mode" {
				if port.PortMode != tpb.SwitchPort_PORTMODE_INVALID {
					return fmt.Errorf("redefinition of switchport mode")
				}
				if parts[2] == "access" {
					port.PortMode = tpb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED
				} else if parts[2] == "trunk" {
					port.PortMode = tpb.SwitchPort_PORTMODE_SWITCHPORT_TAGGED
				} else if parts[2] == "general" {
					port.PortMode = tpb.SwitchPort_PORTMODE_SWITCHPORT_GENERIC
				} else {
					port.PortMode = tpb.SwitchPort_PORTMODE_MANGLED
				}
			}

			if parts[1] == "access" {
				if port.PortMode == tpb.SwitchPort_PORTMODE_INVALID {
					port.PortMode = tpb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED
				}
				if len(parts) > 3 && parts[2] == "vlan" {
					vlan, err := strconv.Atoi(parts[3])
					if err != nil {
						return fmt.Errorf("invalid vlan: %q", parts[3])
					}
					port.VlanNative = int32(vlan)
				}
			}

			if parts[1] == "trunk" {
				if len(parts) >= 5 && parts[2] == "allowed" && parts[3] == "vlan" {
					vlans := strings.Split(parts[4], ",")
					for _, vlan := range vlans {
						vlanNum, err := strconv.Atoi(vlan)
						if err != nil {
							return fmt.Errorf("invalid vlan: %q", parts[3])
						}
						port.VlanTagged = append(port.VlanTagged, int32(vlanNum))
					}
				}
			}
		} else if len(parts) >= 2 && parts[0] == "mtu" {
			mtu, err := strconv.Atoi(parts[1])
			if err != nil {
				return fmt.Errorf("invalid mtu: %q", parts[3])
			}
			port.Mtu = int32(mtu)
		} else if len(parts) >= 2 && parts[0] == "spanning-tree" && parts[1] == "portfast" {
			port.SpanningTreeMode = tpb.SwitchPort_SPANNING_TREE_MODE_PORTFAST
		}
	}

	// no mode -> access
	if port.PortMode == tpb.SwitchPort_PORTMODE_INVALID {
		port.PortMode = tpb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED
	}

	// apply defaults
	if port.Mtu == 0 {
		port.Mtu = 1500
	}
	if port.SpanningTreeMode == tpb.SwitchPort_SPANNING_TREE_MODE_INVALID {
		port.SpanningTreeMode = tpb.SwitchPort_SPANNING_TREE_MODE_AUTO_PORTFAST
	}

	// sanitize
	if port.PortMode == tpb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED {
		port.VlanTagged = []int32{}
		port.Prefixes = []string{}
		if port.VlanNative == 0 {
			port.VlanNative = 1
		}
	} else if port.PortMode == tpb.SwitchPort_PORTMODE_SWITCHPORT_TAGGED {
		port.VlanNative = 0
		port.Prefixes = []string{}
	} else if port.PortMode == tpb.SwitchPort_PORTMODE_SWITCHPORT_GENERIC {
		port.Prefixes = []string{}
		if port.VlanNative == 0 {
			port.VlanNative = 1
		}
	}
	return nil
}

func (s *service) GetPorts(ctx context.Context, req *tpb.GetPortsRequest) (*tpb.GetPortsResponse, error) {
	cli, err := s.connect()
	if err != nil {
		return nil, status.Error(codes.Unavailable, "could not connect to switch")
	}
	defer s.disconnect()
	res := &tpb.GetPortsResponse{}

	statusLines, _, err := cli.runCommand(ctx, "show interface status")
	if err != nil {
		return nil, status.Error(codes.Unavailable, "could not get interface status from switch")
	}

	err = s.parseInterfaceStatus(res, statusLines)
	if err != nil {
		return nil, status.Errorf(codes.Unavailable, "could not parse interface status from switch: %v", err)
	}

	for _, port := range res.Ports {
		configLines, _, err := cli.runCommand(ctx, "show run interface "+port.Name)
		if err != nil {
			return nil, status.Error(codes.Unavailable, "could not get interface config from switch")
		}
		err = s.parseInterfaceConfig(port, configLines)
		if err != nil {
			return nil, status.Errorf(codes.Unavailable, "could not parse interface config from switch: %v", err)
		}
	}

	return res, nil
}

func main() {
	flag.StringVar(&flagSwitchAddress, "switch_address", "127.0.0.1:23", "Telnet address of M6220")
	flag.StringVar(&flagSwitchUsername, "switch_username", "admin", "Switch login username")
	flag.StringVar(&flagSwitchPassword, "switch_password", "admin", "Switch login password")
	flag.Parse()

	s := &service{
		connectionSemaphore: make(chan int, 1),
	}

	m := mirko.New()
	if err := m.Listen(); err != nil {
		glog.Exitf("Listen(): %v", err)
	}

	pb.RegisterM6220ProxyServer(m.GRPC(), s)
	tpb.RegisterSwitchControlServer(m.GRPC(), s)

	if err := m.Serve(); err != nil {
		glog.Exitf("Serve(): %v", err)
	}

	select {}
}
