package main

import (
	"context"
	"crypto/x509"
	"flag"
	"fmt"
	"sort"
	"strings"

	pb "code.hackerspace.pl/hscloud/bgpwtf/cccampix/proto"
	"github.com/golang/glog"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
)

var (
	flagVerifier string
	flagIdentity string
	flagRouterID string
	flagV6       bool
	flagLocalIP  string
	flagUpstream bool
)

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

func main() {
	flag.StringVar(&flagVerifier, "verifier", "", "Verifier endpoint")
	flag.StringVar(&flagIdentity, "identity", "", "Router identity")
	flag.StringVar(&flagRouterID, "router_id", "", "Router ID")
	flag.StringVar(&flagLocalIP, "local_ip", "", "Local IP")
	flag.BoolVar(&flagV6, "v6", false, "V6")
	flag.BoolVar(&flagUpstream, "upstream", false, "Is an upstream router")

	flag.Parse()

	if flagVerifier == "" {
		glog.Exit("verifier must be set")
	}
	if flagIdentity == "" {
		glog.Exit("identity must be set")
	}
	if flagRouterID == "" {
		glog.Exit("router_id must be set")
	}

	cpool, _ := x509.SystemCertPool()
	creds := credentials.NewClientTLSFromCert(cpool, "")
	conn, err := grpc.Dial(flagVerifier, grpc.WithTransportCredentials(creds))
	if err != nil {
		glog.Exitf("Dial: %v", err)
	}

	ctx := context.Background()
	verifier := pb.NewVerifierClient(conn)

	req := &pb.RouterHeartbeatRequest{
		Name: flagIdentity,
	}

	res, err := verifier.RouterHeartbeat(ctx, req)
	if err != nil {
		glog.Exitf("RouterHeartbeat: %v", err)
	}

	var config string
	if flagV6 {
		config = `
log syslog all;

router id %s;
debug protocols { states, interfaces, events };

timeformat base iso long;
timeformat log iso long;
timeformat protocol iso long;
timeformat route iso long;

define ourASN = %d;
define filteredNumber = 65666;
define customerNumber = 65667;
define martian = 1;
define prefixTooLong64 = 2;
define prefixTooLong24 = 3;
define pathBogon = 4;
define pathTooLong = 5;
define pathFirstNotPeer = 6;
define prefixFiltered = 9;

protocol device {}

function net_martians() {
    return net ~ [ fc00::/7+, fec0::/10+, ::/128-, ::/0{0,15}, ::/0{49,128} ];
}

function generic_in() {
	if net_martians() then {
		bgp_large_community.add((ourASN, filteredNumber, martian));
		return false;
	}
	if bgp_path.len > 64 then {
		bgp_large_community.add((ourASN, filteredNumber, pathTooLong));
		return false;
	}
	if net.len > 64 then {
		bgp_large_community.add((ourASN, filteredNumber, prefixTooLong64));
		return false;
	}
	return true;
}
`
		config = fmt.Sprintf(config, flagRouterID, 208521)
	} else {
		config = `
log syslog all;

router id %s;
debug protocols { states, interfaces, events };

timeformat base iso long;
timeformat log iso long;
timeformat protocol iso long;
timeformat route iso long;

define ourASN = %d;
define filteredNumber = 65666;
define customerNumber = 65667;
define martian = 1;
define prefixTooLong64 = 2;
define prefixTooLong24 = 3;
define pathBogon = 4;
define pathTooLong = 5;
define pathFirstNotPeer = 6;
define prefixFiltered = 9;

protocol device {}

function net_martians() {
    return net ~ [ 169.254.0.0/16+, 172.16.0.0/12+, 192.168.0.0/16+, 10.0.0.0/8+,
        127.0.0.0/8+, 224.0.0.0/4+, 240.0.0.0/4+, 0.0.0.0/32-, 0.0.0.0/0{25,32}, 0.0.0.0/0{0,7} ];
}

function generic_in() {
	if net_martians() then {
		bgp_large_community.add((ourASN, filteredNumber, martian));
		return false;
	}
	if bgp_path.len > 64 then {
		bgp_large_community.add((ourASN, filteredNumber, pathTooLong));
		return false;
	}
	if net.len > 24 then {
		bgp_large_community.add((ourASN, filteredNumber, prefixTooLong24));
		return false;
	}
	return true;
}
`
		config = fmt.Sprintf(config, flagRouterID, 208521)
	}

	if flagUpstream {
		config += `
protocol kernel {
    scan time 60;
    import none;
    export all;
}

filter UPSTREAM_C3NOC_IN {
  if net_martians() then reject;
  if bgp_path.len > 64 then reject;
  accept;
}

filter UPSTREAM_C3NOC_OUT {
  accept;
}

`
		if flagV6 {
			config += `
protocol bgp UPSTREAM_C3NOC {
  import filter UPSTREAM_C3NOC_IN;
  export filter UPSTREAM_C3NOC_OUT;
  description "UPSTREAM AS13020";

  local 2a0d:eb02:4242:4242::7 as 208521;
  neighbor 2a0d:eb02:4242:4242::250 as 13020;
}
`
		} else {
			config += `
protocol bgp UPSTREAM_C3NOC {
  import filter UPSTREAM_C3NOC_IN;
  export filter UPSTREAM_C3NOC_OUT;

  local 185.236.243.7 as 208521;
  neighbor 185.236.243.250 as 13020;
}
`
		}
	}

	sort.Slice(res.AsConfigs, func(i, j int) bool {
		return res.AsConfigs[i].Asn < res.AsConfigs[j].Asn
	})

	for _, asc := range res.AsConfigs {
		sort.Slice(asc.Routers, func(i, j int) bool {
			return asc.Routers[i].Password < asc.Routers[j].Password
		})
		for i, router := range asc.Routers {
			addr := ""
			if flagV6 {
				addr = router.Ipv6
			} else {
				addr = router.Ipv4
			}
			if addr == "" {
				continue
			}
			peerid := fmt.Sprintf("PEER_%d_%d", asc.Asn, i)
			prefixes := []string{}
			for _, prefix := range asc.Prefixes {
				if flagV6 && !strings.Contains(prefix.Prefix, ":") {
					continue
				}
				if !flagV6 && !strings.Contains(prefix.Prefix, ".") {
					continue
				}
				parts := strings.Split(prefix.Prefix, "/")
				addr := parts[0]
				bits := parts[1]
				filter := fmt.Sprintf("%s/%s{%s,%d}", addr, bits, bits, prefix.MaxLength)
				if fmt.Sprintf("%d", prefix.MaxLength) == bits {
					filter = fmt.Sprintf("%s/%s", addr, bits)
				}
				prefixes = append(prefixes, filter)
			}
			if len(prefixes) == 0 {
				continue
			}
			allowed := strings.Join(prefixes, ",")

			part := `
filter %s_in {
	if !generic_in() then reject;
	if bgp_path.first != %d then {
		bgp_large_community.add((ourASN, filteredNumber, pathFirstNotPeer));
		reject;
	}
	if bgp_path.last != %d then {
		bgp_large_community.add((ourASN, filteredNumber, pathFirstNotPeer));
		reject;
	}
	if ! (net ~ [ %s ]) then {
		bgp_large_community.add((ourASN, filteredNumber, prefixFiltered));
		reject;
	}
	bgp_large_community.add((ourASN, customerNumber, 2137));
	accept;
}
`
			part = fmt.Sprintf(part, peerid, asc.Asn, asc.Asn, allowed)
			config += part

			part = `
filter %s_out {
	if (ourASN, customerNumber, 2137) ~ bgp_large_community then reject;
	accept;
}
`
			part = fmt.Sprintf(part, peerid)
			config += part

			part = `
protocol bgp %s {
	local %s as 208521;
	description "PEER AS%d R%d";
	neighbor %s as %d;
	import filter %s_in;
	import keep filtered on;
	export filter %s_out;
	password "%s";
}
`
			part = fmt.Sprintf(part, peerid, flagLocalIP, asc.Asn, i, addr, asc.Asn, peerid, peerid, router.Password)
			config += part
		}
	}

	fmt.Println(config)
}
