package provider

// IANA is not a full provider - we use it to determine the relevant IRR for a given aut-num.

import (
	"context"
	"fmt"
	"strconv"
	"strings"

	"github.com/golang-collections/go-datastructures/augmentedtree"
	"github.com/golang/glog"

	"code.hackerspace.pl/hscloud/bgpwtf/cccampix/irr/whois"
)

// Possible IRRs that AS blocks can be delegated to.
type IRR int

const (
	IRR_UNKNOWN IRR = iota
	IRR_ARIN
	IRR_RIPE
)

func (i IRR) String() string {
	return []string{
		"UNKNOWN",
		"ARIN",
		"RIPE",
	}[i]
}

// IANA access service.
type IANA struct {
	// Interval tree of AS block delegation to IRRs. We use this to not
	// keep hitting the IANA whois unnecessariy.
	cache augmentedtree.Tree
	// The tree library needs intervals to have a unique ID. We use a counter
	// for this effect.
	id uint64
}

func NewIANA() *IANA {
	return &IANA{
		cache: augmentedtree.New(1),
	}
}

func (i *IANA) nextID() uint64 {
	res := i.id
	i.id += 1
	return res
}

// delegation implements the Interval interface for the interval tree.
type delegation struct {
	to   IRR
	id   uint64
	low  int64
	high int64
}

func (d *delegation) LowAtDimension(n uint64) int64 {
	if n != 1 {
		panic(fmt.Sprintf("dimension too high (%d)", n))
	}
	return d.low
}

func (d *delegation) HighAtDimension(n uint64) int64 {
	if n != 1 {
		panic(fmt.Sprintf("dimension too high (%d)", n))
	}
	return d.high
}

func (d *delegation) OverlapsAtDimension(i augmentedtree.Interval, n uint64) bool {
	if n != 1 {
		return false
	}

	if i.LowAtDimension(1) <= d.HighAtDimension(1) && i.HighAtDimension(1) >= d.LowAtDimension(1) {
		return true
	}

	return false
}

func (d *delegation) ID() uint64 {
	return d.id
}

// Who returns the responsible IRR (or UNKNOWN) for a given AS.
func (i *IANA) Who(ctx context.Context, asn uint64) (IRR, error) {
	q := &delegation{
		id:   i.nextID(),
		low:  int64(asn),
		high: int64(asn),
	}

	res := i.cache.Query(q)
	if len(res) > 0 {
		return res[0].(*delegation).to, nil
	}

	// No cache entry, query whois.
	glog.Infof("Cache miss for AS%d", asn)
	data, err := whois.Query(ctx, "whois.iana.org:43", fmt.Sprintf("AS%d", asn))
	if err != nil {
		return IRR_UNKNOWN, err
	}

	// We not only find the responsible IRR, but also the delegation bounds
	// to feed the interval tree.
	lines := strings.Split(data, "\n")
	var lower int64
	var upper int64
	var irr IRR
	for _, line := range lines {
		parts := strings.Fields(line)
		if len(parts) == 2 && parts[0] == "as-block:" {
			bounds := strings.Split(parts[1], "-")
			if len(bounds) != 2 {
				return IRR_UNKNOWN, fmt.Errorf("unparseable as-block: %v", parts[1])
			}
			lower, err = strconv.ParseInt(bounds[0], 10, 64)
			if err != nil {
				return IRR_UNKNOWN, fmt.Errorf("unparseable as-block: %v", parts[1])
			}
			upper, err = strconv.ParseInt(bounds[1], 10, 64)
			if err != nil {
				return IRR_UNKNOWN, fmt.Errorf("unparseable as-block: %v", parts[1])
			}
		}
		if len(parts) > 2 && parts[0] == "organisation:" {
			switch {
			case strings.Contains(line, "RIPE NCC"):
				irr = IRR_RIPE
			case strings.Contains(line, "ARIN"):
				irr = IRR_ARIN
			}
		}
	}

	if lower == 0 || upper == 0 {
		return IRR_UNKNOWN, nil
	}

	glog.Infof("Saving %d-%d AS blocks delegation (%s) to cache", lower, upper, irr.String())

	// Insert into tree.
	q = &delegation{
		id:   i.nextID(),
		to:   irr,
		low:  lower,
		high: upper + 1,
	}

	i.cache.Add(q)

	return irr, nil
}
