// meta4ra -- Metalink 4.0 utilities
// Copyright (C) 2021-2026 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package main

import (
	"encoding/xml"
	"flag"
	"fmt"
	"io/fs"
	"log"
	"os"
	"strings"

	meta4ra "go.stargrave.org/meta4ra/v2/internal"
)

func runList() {
	doSize := flag.Bool("size", false, "Print file's size")
	doHashes := flag.Bool("hashes", false, "Print file's hashes")
	doSig := flag.Bool("sig", false, "Extract signature files")
	flag.Usage = func() {
		fmt.Fprintf(flag.CommandLine.Output(),
			"Usage: %s [options] FILE.meta4 [FILE]\n", os.Args[0])
		flag.PrintDefaults()
		fmt.Fprint(flag.CommandLine.Output(), `
If FILE is not specified, then list all files of .meta4.
Otherwise list all URLs of the given FILE.
`)
	}
	flag.Parse()

	if *showVersion {
		fmt.Println(meta4ra.Version())
		return
	}
	if *showWarranty {
		fmt.Println(meta4ra.Warranty)
		return
	}

	if flag.NArg() < 1 {
		flag.Usage()
		os.Exit(1)
	}
	var meta meta4ra.Metalink
	{
		data, err := os.ReadFile(flag.Arg(0))
		if err != nil {
			log.Fatal(err)
		}
		err = xml.Unmarshal(data, &meta)
		if err != nil {
			log.Fatal(err)
		}
	}

	bad := false
	for _, f := range meta.Files {
		if flag.NArg() == 1 {
			for _, sig := range f.Signature {
				if !*doSig {
					continue
				}
				var fn string
				switch sig.MediaType {
				case meta4ra.SigMediaTypePGP:
					fn = f.Name + ".asc"
				case meta4ra.SigMediaTypeSSH:
					fn = f.Name + ".sig"
				}
				if fn == "" {
					continue
				}
				if err := os.WriteFile(
					fn,
					[]byte(strings.TrimPrefix(sig.Signature, "\n")),
					fs.FileMode(0o666),
				); err != nil {
					log.Println("error:", f.Name, "can not save signature:", err)
					bad = true
				}
			}
			fmt.Println(f.Name)
		} else {
			if f.Name != flag.Arg(1) {
				continue
			}
			if *doSize {
				fmt.Println(f.Size)
				break
			}
			if *doHashes {
				for _, h := range f.Hashes {
					fmt.Println(h.Type, h.Hash)
				}
				break
			}
			for _, u := range f.URLs {
				fmt.Println(u.String())
			}
			break
		}
	}
	if bad {
		os.Exit(1)
	}
}
