package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"strings"
)

func cmdClearServices(args []string) error {
	fs := flag.NewFlagSet("clear-services", flag.ExitOnError)
	dryRun := fs.Bool("dry-run", false, "list what would be deleted without deleting")
	confirm := fs.Bool("confirm", false, "actually delete (required)")
	accountFilter := fs.String("account", "", "only clear services for this account ID")
	if err := fs.Parse(args); err != nil {
		return err
	}

	if !*dryRun && !*confirm {
		return fmt.Errorf("clear-services requires --confirm to actually delete, or --dry-run to preview")
	}

	c, err := NewClient()
	if err != nil {
		return err
	}

	// Fetch all services.
	items, _, err := c.listAll("/services", 1000, decodeListPage)
	if err != nil {
		return fmt.Errorf("list services: %w", err)
	}

	// Filter by account if requested.
	var toDelete []Service
	for _, rm := range items {
		var s Service
		if err := json.Unmarshal(rm, &s); err != nil {
			log.Printf("skip unparseable service: %v", err)
			continue
		}
		if *accountFilter != "" && s.Account != *accountFilter {
			continue
		}
		toDelete = append(toDelete, s)
	}

	if len(toDelete) == 0 {
		fmt.Println("no services to delete")
		return nil
	}

	fmt.Printf("%d services to delete", len(toDelete))
	if *accountFilter != "" {
		fmt.Printf(" for account %q", *accountFilter)
	}
	fmt.Println()

	if *dryRun {
		for _, s := range toDelete {
			macs := attachmentMACs(s)
			fmt.Printf("  %s  account=%s  macs=%s  up=%d down=%d\n",
				s.ID, s.Account, strings.Join(macs, ","), s.UpSpeed, s.DownSpeed)
		}
		fmt.Println("--dry-run: no services were deleted")
		return nil
	}

	// Actually delete.
	var deleted, failed int
	for _, s := range toDelete {
		path := apiPrefix + "/services/" + pathID(s.ID)
		if err := c.del(path); err != nil {
			log.Printf("FAIL %s: %v", s.ID, err)
			failed++
		} else {
			macs := attachmentMACs(s)
			fmt.Printf("deleted %s  account=%s  macs=%s\n", s.ID, s.Account, strings.Join(macs, ","))
			deleted++
		}
	}

	fmt.Printf("\n%d deleted, %d failed\n", deleted, failed)
	if failed > 0 {
		return fmt.Errorf("%d deletions failed", failed)
	}
	return nil
}

func attachmentMACs(s Service) []string {
	var macs []string
	for _, a := range s.Attachments {
		if a.CPEMac != "" {
			macs = append(macs, a.CPEMac)
		} else if a.CPESerial != "" {
			macs = append(macs, "sn:"+a.CPESerial)
		} else if a.CPEIMSI != "" {
			macs = append(macs, "imsi:"+a.CPEIMSI)
		} else if a.Username != "" {
			macs = append(macs, "u:"+a.Username)
		} else if len(a.NetworkPrefixes) > 0 {
			macs = append(macs, "pfx:"+a.NetworkPrefixes[0])
		}
	}
	return macs
}
