Write a Golang program that scrapes a given website for all internal and external links, stores them in a SQLite database, and generates a sitemap in XML format.
PLAINFORMAT
package main

import (
	"database/sql"
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"

	"github.com/PuerkitoBio/goquery"
	_ "github.com/mattn/go-sqlite3"
)

type SitemapIndex struct {
	XMLName xml.Name `xml:"sitemapindex"`
	Sitemaps []Sitemap `xml:"sitemap"`
}

type Sitemap struct {
	Loc string `xml:"loc"`
}

func main() {
	if len(os.Args) != 2 {
		fmt.Println("Usage: go run main.go <url>")
		os.Exit(1)
	}
	targetURL := os.Args[1]

	db, err := sql.Open("sqlite3", "./links.db")
	checkError(err)
	defer db.Close()

	createTable(db)

	internalLinks, externalLinks := scrapeLinks(targetURL)

	storeLinks(internalLinks, "internal", db)
	storeLinks(externalLinks, "external", db)

	generateSitemap(internalLinks)
}

func checkError(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

func createTable(db *sql.DB) {
	query := `
	CREATE TABLE IF NOT EXISTS links (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		url TEXT NOT NULL UNIQUE,
		type TEXT NOT NULL
	);
	`
	_, err := db.Exec(query)
	checkError(err)
}

func scrapeLinks(targetURL string) (map[string]bool, map[string]bool) {
	resp, err := http.Get(targetURL)
	checkError(err)
	defer resp.Body.Close()

	doc, err := goquery.NewDocumentFromReader(resp.Body)
	checkError(err)

	internalLinks := make(map[string]bool)
	externalLinks := make(map[string]bool)

	doc.Find("a[href]").Each(func(_ int, s *goquery.Selection) {
		href, _ := s.Attr("href")
		linkURL, err := url.Parse(href)
		checkError(err)

		if linkURL.IsAbs() {
			if linkURL.Host == resp.Request.URL.Host {
				internalLinks[linkURL.String()] = true
			} else {
				externalLinks[linkURL.String()] = true
			}
		} else {
			resolvedURL := resp.Request.URL.ResolveReference(linkURL)
			internalLinks[resolvedURL.String()] = true
		}
	})

	return internalLinks, externalLinks
}

func storeLinks(links map[string]bool, linkType string, db *sql.DB) {
	for link := range links {
		insertLink(link, linkType, db)
	}
}

func insertLink(url, linkType string, db *sql.DB) {
	query := "INSERT OR IGNORE INTO links (url, type) VALUES (?, ?)"
	stmt, err := db.Prepare(query)
	checkError(err)

	_, err = stmt.Exec(url, linkType)
	checkError(err)
}

func generateSitemap(internalLinks map[string]bool) {
	sitemaps := make([]Sitemap, 0, len(internalLinks))

	for link := range internalLinks {
		sitemaps = append(sitemaps, Sitemap{Loc: link})
	}

	sitemapIndex := SitemapIndex{
		Sitemaps: sitemaps,
	}

	xmlData, err := xml.MarshalIndent(sitemapIndex, "", "  ")
	checkError(err)

	err = ioutil.WriteFile("sitemap.xml", xmlData, 0644)
	checkError(err)

	fmt.Println("Generated sitemap.xml")
}