package schema

import (
	"context"
	"os"
	"strings"
	"time"

	"xorm.io/builder"
)

func init() {
	RegisterModel(new(APRSStation))
	RegisterModel(new(APRSPacket))
}

type APRSStation struct {
	ID            int64     `xorm:"pk autoincr" json:"id"`
	Call          string    `xorm:"varchar(10) unique not null" json:"call"`
	Symbol        string    `xorm:"varchar(2)" json:"symbol"`
	FirstHeardAt  time.Time `xorm:"timestamp not null"`
	LastHeardAt   time.Time `xorm:"timestamp not null"`
	LastLatitude  *float64  `xorm:"numeric(10,8)" json:"latitude,omitempty"`
	LastLongitude *float64  `xorm:"numeric(11,8)" json:"longitude,omitempty"`
}

func GetAPRSStation(ctx context.Context, call string) (*APRSStation, error) {
	station := new(APRSStation)
	has, err := Query(ctx).
		Where(builder.Eq{`"call"`: strings.ToUpper(call)}).
		Get(station)
	if err != nil {
		return nil, err
	} else if !has {
		return nil, os.ErrNotExist
	}
	return station, nil
}

func (station APRSStation) GetPackets(ctx context.Context) ([]*APRSPacket, error) {
	packets := make([]*APRSPacket, 0, 10)
	return packets, Query(ctx).
		Where(builder.Eq{"`station_id`": station.ID}).
		Find(&packets)
}

type APRSPacket struct {
	ID          int64     `xorm:"pk autoincr" json:"id"`
	RadioID     int64     `xorm:"index" json:"radio_id"`
	Radio       *Radio    `xorm:"-" json:"radio"`
	StationID   int64     `json:"-"`
	Source      string    `xorm:"varchar(10) not null" json:"src"`
	Destination string    `xorm:"varchar(10) not null" json:"dst"`
	Path        string    `xorm:"varchar(88) not null default ''" json:"path"`
	Comment     string    `xorm:"varchar(250)" json:"comment"`
	Latitude    *float64  `xorm:"numeric(10,8)" json:"latitude,omitempty"`
	Longitude   *float64  `xorm:"numeric(11,8)" json:"longitude,omitempty"`
	Symbol      string    `xorm:"varchar(2)" json:"symbol"`
	Raw         string    `json:"raw"`
	ReceivedAt  time.Time `json:"received_at"`
	//Station     *APRSStation `xorm:"-" json:"station"`
}

func GetAPRSPackets(ctx context.Context, limit int) ([]*APRSPacket, error) {
	packets := make([]*APRSPacket, 0, limit)
	return packets, Query(ctx).
		OrderBy("`received_at` DESC").
		Limit(limit).
		Find(&packets)
}

func GetAPRSPacketsBySource(ctx context.Context, source string) ([]*APRSPacket, error) {
	packets := make([]*APRSPacket, 0, 100)
	return packets, Query(ctx).
		Where(builder.Eq{"source": strings.ToUpper(source)}).
		OrderBy("`received_at` DESC").
		Find(&packets)
}

func GetAPRSPacketsByDestination(ctx context.Context, destination string) ([]*APRSPacket, error) {
	packets := make([]*APRSPacket, 0, 100)
	return packets, Query(ctx).
		Where(builder.Eq{"destination": strings.ToUpper(destination)}).
		OrderBy("`received_at` DESC").
		Find(&packets)
}
