// Package ristypes defines the data structures for RIS Live BGP messages and announcements.
package ristypes

import (
	"encoding/json"
	"time"
)

// ASPath represents an AS path that may contain nested AS sets
type ASPath []int

// UnmarshalJSON implements custom JSON unmarshaling to flatten nested arrays
func (p *ASPath) UnmarshalJSON(data []byte) error {
	// First try to unmarshal as a simple array of integers
	var simple []int
	if err := json.Unmarshal(data, &simple); err == nil {
		*p = ASPath(simple)

		return nil
	}

	// If that fails, unmarshal as array of interfaces and flatten
	var raw []interface{}
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}

	// Flatten the array
	result := make([]int, 0)
	for _, item := range raw {
		switch v := item.(type) {
		case float64:
			result = append(result, int(v))
		case []interface{}:
			// Nested array - flatten it
			for _, nested := range v {
				if num, ok := nested.(float64); ok {
					result = append(result, int(num))
				}
			}
		}
	}

	*p = ASPath(result)

	return nil
}

// RISLiveMessage represents the outer wrapper from the RIS Live stream
type RISLiveMessage struct {
	Type string     `json:"type"`
	Data RISMessage `json:"data"`
}

// RISMessage represents a message from the RIS Live stream
type RISMessage struct {
	Type            string            `json:"type"`
	Timestamp       float64           `json:"timestamp"`
	ParsedTimestamp time.Time         `json:"-"` // Parsed from Timestamp field
	Peer            string            `json:"peer"`
	PeerASN         string            `json:"peer_asn"`
	ID              string            `json:"id"`
	Host            string            `json:"host"`
	RRC             string            `json:"rrc,omitempty"`
	MrtTime         float64           `json:"mrt_time,omitempty"`
	SocketTime      float64           `json:"socket_time,omitempty"`
	Path            ASPath            `json:"path,omitempty"`
	Community       [][]int           `json:"community,omitempty"`
	Origin          string            `json:"origin,omitempty"`
	MED             *int              `json:"med,omitempty"`
	LocalPref       *int              `json:"local_pref,omitempty"`
	Announcements   []RISAnnouncement `json:"announcements,omitempty"`
	Withdrawals     []string          `json:"withdrawals,omitempty"`
	Raw             string            `json:"raw,omitempty"`
}

// RISAnnouncement represents announcement data within a RIS message
type RISAnnouncement struct {
	NextHop  string   `json:"next_hop"`
	Prefixes []string `json:"prefixes"`
}
