package provider

// Support for the RIPE IRR.
// We use the RIPE REST DB API.

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"

	pb "code.hackerspace.pl/hscloud/bgpwtf/cccampix/proto"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

type ripeResponse struct {
	Objects struct {
		Object []ripeObject `json:"object"`
	} `json:"objects"`
}

type ripeObject struct {
	Type       string `json:"type"`
	Attributes struct {
		Attribute []ripeAttribute `json:"attribute"`
	} `json:"attributes"`
}

type ripeAttribute struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}

type ripe struct {
	sem chan struct{}
}

func NewRIPE(limit int) Provider {
	return &ripe{
		sem: make(chan struct{}, limit),
	}
}

func (r *ripe) Query(ctx context.Context, as uint64) (*pb.IRRQueryResponse, error) {
	r.sem <- struct{}{}
	defer func() {
		<-r.sem
	}()

	req, err := http.NewRequest("GET", fmt.Sprintf("http://rest.db.ripe.net/ripe/aut-num/AS%d.json", as), nil)
	if err != nil {
		return nil, err
	}

	req = req.WithContext(ctx)
	client := http.DefaultClient

	res, err := client.Do(req)
	if err != nil {
		return nil, status.Errorf(codes.Unavailable, "could not run GET to RIPE: %v", err)
	}
	defer res.Body.Close()
	bytes, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, status.Errorf(codes.Unavailable, "could not read response from RIPE: %v", err)
	}

	data := ripeResponse{}
	err = json.Unmarshal(bytes, &data)
	if err != nil {
		return nil, status.Errorf(codes.Unavailable, "could not decode response from RIPE: %v", err)
	}

	if len(data.Objects.Object) != 1 {
		return nil, status.Error(codes.NotFound, "could not retrieve aut-num from RIPE")
	}

	attributes := make([]rpslRawAttribute, len(data.Objects.Object[0].Attributes.Attribute))

	for i, attr := range data.Objects.Object[0].Attributes.Attribute {
		attributes[i].name = attr.Name
		attributes[i].value = attr.Value
	}

	return &pb.IRRQueryResponse{
		Source:     pb.IRRQueryResponse_SOURCE_RIPE,
		Attributes: parseAttributes(attributes),
	}, nil
}
