package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
)

/*
#! /bin/bash

set -e
set -u

rawraw="$( \
   curl "https://www.namesilo.com/api/dnsListRecords?version=1&type=xml&key=7a26bd4b7aedbc6c44f56af38&domain=blapointe.com" 2> /dev/null \
   | xq .namesilo \
)"
echo $rawraw | jq . >&2
ip="$( \
   echo "$rawraw" \
   | jq -r .request.ip \
)"
echo ip $ip >&2
raw="$( \
   echo "$rawraw" \
   | jq -c '.reply.resource_record[]' \
   | grep \*.home.blapointe \
   | jq -c . \
   | jq -c . \
)"
echo raw $raw >&2
rid="$( \
   echo "$raw" \
   | jq -r .record_id \
)"
ip="$(curl icanhazip.com 2> /dev/null)"
echo $rid
echo curl "https://www.namesilo.com/api/dnsUpdateRecord?version=1&type=xml&key=7a26bd4b7aedbc6c44f56af38&domain=blapointe.com&rrid=$rid&rrhost=*.home&rrvalue=$ip&rrttl=7207"
curl "https://www.namesilo.com/api/dnsUpdateRecord?version=1&type=xml&key=7a26bd4b7aedbc6c44f56af38&domain=blapointe.com&rrid=$rid&rrhost=*.home&rrvalue=$ip&rrttl=7207" 2> /dev/null \
   | xq .
*/

func main() {
	domain := flag.String("domain", "blapointe.com", "domain to point to this IP")
	subdomain := flag.String("prefix", "*.home.", "subdomain to point to this IP, empty str ok")
	apikey := flag.String("apikey", "7a26bd4b7aedbc6c44f56af38", "namesilo api key")
	flag.Parse()
	uri := "https://www.namesilo.com/api/dnsListRecords?version=1&type=json&key=" + *apikey + "&domain=" + *domain
	log.Printf("uri=%s", uri)
	resp, err := http.Get(uri)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	b, _ := io.ReadAll(resp.Body)
	if resp.StatusCode != http.StatusOK {
		panic(fmt.Sprintf("(%d) %s", resp.StatusCode, b))
	}
	var rawraw struct {
		//Namesilo struct {
		Request struct {
			IP string `json:"ip"`
		} `json:"request"`
		Reply struct {
			ResourceRecord []struct {
				Host     string `json:"host"`
				RecordID string `json:"record_id"`
			} `json:"resource_record"`
		} `json:"reply"`
		//} `json:"namesilo"`
	}
	if err := json.NewDecoder(bytes.NewReader(b)).Decode(&rawraw); err != nil {
		panic(err)
	}
	ip := rawraw.Request.IP
	log.Printf("%d: %+v (%s)", resp.StatusCode, rawraw, b)
	log.Printf("looking for host == %s", *subdomain+*domain)
	for _, v := range rawraw.Reply.ResourceRecord {
		if v.Host != *subdomain+*domain {
			continue
		}
		rrid := v.RecordID
		log.Printf("found %s%s: %v %v", *subdomain, *domain, rrid, ip)
		url := fmt.Sprintf("https://www.namesilo.com/api/dnsUpdateRecord?version=1&type=json&key="+*apikey+"&domain="+*domain+"&rrid=%s&rrhost="+strings.TrimRight(*subdomain, ".")+"&rrvalue=%s&rrttl=3600", rrid, ip)
		log.Printf("updating via %s", url)
		resp, err := http.Get(url)
		if err != nil {
			panic(err)
		}
		defer resp.Body.Close()
		if resp.StatusCode != http.StatusOK {
			panic(resp.StatusCode)
		}
		b, _ := ioutil.ReadAll(resp.Body)
		log.Printf("%v: %s", err, b)
		return
	}
	url := fmt.Sprintf("https://www.namesilo.com/api/dnsAddRecord?version=1&type=json&key="+*apikey+"&domain="+*domain+"&rrtype=A&rrhost="+strings.TrimRight(*subdomain, ".")+"&rrvalue=%s&rrttl=3600", ip)
	log.Printf("creating via %s", url)
	resp, err = http.Get(url)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		panic(resp.StatusCode)
	}
	b, _ = ioutil.ReadAll(resp.Body)
	log.Printf("%v: %s", err, b)
	return
}
