// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package util

import (
	"archive/tar"
	"bytes"
	"compress/gzip"
	"context"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"go.fuchsia.dev/fuchsia/src/sys/pkg/bin/pm/build"
	"go.fuchsia.dev/fuchsia/tools/lib/logger"
)

// RunCommand executes a command on the host and returns the stdout and stderr
// as byte strings.
func RunCommand(ctx context.Context, name string, arg ...string) ([]byte, []byte, error) {
	logger.Infof(ctx, "running: %s %q", name, arg)
	c := exec.CommandContext(ctx, name, arg...)
	var o bytes.Buffer
	var e bytes.Buffer
	c.Stdout = &o
	c.Stderr = &e
	err := c.Run()
	stdout := o.Bytes()
	stderr := e.Bytes()
	return stdout, stderr, err
}

// Untar untars a tar.gz file into a directory.
func Untar(ctx context.Context, dst string, src string) error {
	logger.Infof(ctx, "untarring %s into %s", src, dst)

	f, err := os.Open(src)
	if err != nil {
		return err
	}
	defer f.Close()

	gz, err := gzip.NewReader(f)
	if err != nil {
		return err
	}
	defer gz.Close()

	tr := tar.NewReader(gz)

	for {
		select {
		case <-ctx.Done():
			return ctx.Err()
		default:
			header, err := tr.Next()
			if err == io.EOF {
				return nil
			} else if err != nil {
				return err
			}

			if err := untarNext(dst, tr, header); err != nil {
				return err
			}
		}
	}
}

func untarNext(dst string, tr *tar.Reader, header *tar.Header) error {
	path := filepath.Join(dst, header.Name)
	info := header.FileInfo()
	if info.IsDir() {
		if err := os.MkdirAll(path, info.Mode()); err != nil {
			return err
		}
	} else {
		if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
			return err
		}

		// Skip entry if path already exists.
		if _, err := os.Stat(path); err == nil {
			return nil
		}

		err := AtomicallyWriteFile(path, info.Mode(), func(f *os.File) error {
			_, err := io.Copy(f, tr)
			return err
		})
		if err != nil {
			return err
		}
	}

	return nil
}

// A StringOr1 is a string that can be unmarshalled from a JSON field that is
// either a string or the number 1. If the field is the number 1 it will be
// converted to the string "1".
type StringOr1 string

func (fi *StringOr1) UnmarshalJSON(b []byte) error {
	if len(b) > 0 && b[0] != '"' {
		var i int
		if err := json.Unmarshal(b, &i); err != nil {
			return err
		}
		if i == 1 {
			*fi = StringOr1("1")
			return nil
		}
		return fmt.Errorf("if version is an int it must be 1, but was %v", i)
	}
	var s string
	if err := json.Unmarshal(b, &s); err != nil {
		return err
	}
	*fi = StringOr1(s)
	return nil
}

type PackageJSON struct {
	// The update package initially used an int instead of a string for the
	// version, and we test that we are still able to update from a build
	// from that era, so we need to be able to read both formats.
	Version StringOr1 `json:"version"`
	Content []string  `json:"content"`
}

func DecodePackagesJSON(rd io.Reader) (*PackageJSON, error) {
	var p PackageJSON

	if err := json.NewDecoder(rd).Decode(&p); err != nil {
		return nil, err
	}

	if p.Version == "" {
		return nil, errors.New("version is required in packages.json format")
	}

	if p.Version != "1" {
		return nil, fmt.Errorf("packages.json version 1 is supported; found version %s", p.Version)
	}

	return &p, nil
}

// ParsePackagesJSON parses an update package's packages.json file for the
// express purpose of returning a map of package names and variant keys
// to the package's Merkle root as a value. This mimics the behavior of the
// function that parsed the legacy "packages" file format.
func ParsePackagesJSON(rd io.Reader) (map[string]build.MerkleRoot, error) {
	p, err := DecodePackagesJSON(rd)
	if err != nil {
		return nil, err
	}

	packages := make(map[string]build.MerkleRoot)
	for _, pkgURL := range p.Content {
		u, err := url.Parse(pkgURL)
		if err != nil {
			return nil, err
		}

		if u.Scheme != "fuchsia-pkg" {
			return nil, fmt.Errorf("%s is not a fuchsia-pkg URL", pkgURL)
		}

		// Path is optional and if it exists, the variant is also optional.
		if u.Path != "" {
			pathComponents := strings.Split(u.Path, "/")
			if len(pathComponents) >= 1 {
				if hash, ok := u.Query()["hash"]; ok {
					merkle, err := build.DecodeMerkleRoot([]byte(hash[0]))
					if err != nil {
						return nil, err
					}

					packages[u.Path[1:]] = merkle
				} else {
					return nil, fmt.Errorf("package %s doesn't have a merkle", u.Path[1:])
				}
			}
		}
	}

	return packages, nil
}

// Replace the host of all package URLs in an update package's packages.json file.
func RehostPackagesJSON(rd io.Reader, w io.Writer, newHostname string) error {
	p, err := DecodePackagesJSON(rd)
	if err != nil {
		return err
	}

	for i, pkgURL := range p.Content {
		u, err := url.Parse(pkgURL)
		if err != nil {
			return err
		}

		u.Host = newHostname

		p.Content[i] = u.String()
	}

	return json.NewEncoder(w).Encode(p)
}

func UpdateHashValuePackagesJSON(
	path string,
	repoName string,
	pkgUrlPath string,
	merkle build.MerkleRoot,
) error {
	if err := AtomicallyWriteFile(path, 0600, func(f *os.File) error {
		src, err := os.Open(path)
		if err != nil {
			return fmt.Errorf("failed to open packages.json %q: %w", path, err)
		}
		defer src.Close()

		p, err := DecodePackagesJSON(src)
		if err != nil {
			return err
		}

		for i, pkgURL := range p.Content {
			u, err := url.Parse(pkgURL)
			if err != nil {
				return err
			}

			if u.Host == repoName && u.Path == "/"+pkgUrlPath {
				queryValues := u.Query()
				queryValues.Set("hash", merkle.String())
				u.RawQuery = queryValues.Encode()
			}

			p.Content[i] = u.String()
		}

		return json.NewEncoder(f).Encode(p)
	}); err != nil {
		return fmt.Errorf("failed to atomically overwrite %q: %w", path, err)
	}

	return nil
}

func ParseImagesJSON(rd io.Reader) (ImagesManifest, error) {
	var i ImagesManifest

	if err := json.NewDecoder(rd).Decode(&i); err != nil {
		return ImagesManifest{}, err
	}

	if i.Version != "1" {
		return ImagesManifest{}, fmt.Errorf("images.json version 1 is supported; found version %s", i.Version)
	}

	return i, nil
}

func UpdateImagesJSON(
	path string,
	images ImagesManifest,
) error {
	return AtomicallyWriteFile(path, 0600, func(f *os.File) error {
		return json.NewEncoder(f).Encode(images)
	})
}

func Sha256File(path string) (string, error) {
	f, err := os.Open(path)
	if err != nil {
		return "", nil
	}
	defer f.Close()

	h := sha256.New()
	if _, err := io.Copy(h, f); err != nil {
		return "", err
	}

	return hex.EncodeToString(h.Sum(nil)), nil
}

// ParsePackageUrl parses a string into a URL and a MerkleRoot
func ParsePackageUrl(urlString string) (*url.URL, build.MerkleRoot, error) {
	url, err := url.Parse(urlString)
	if err != nil {
		return nil, build.MerkleRoot{}, fmt.Errorf("could not parse url %s: %w", urlString, err)
	}

	merkleString := url.Query()["hash"]
	merkle, err := build.DecodeMerkleRoot([]byte(merkleString[0]))
	if err != nil {
		return nil, build.MerkleRoot{}, fmt.Errorf("failed to decode merkle from %s: %w", urlString, err)
	}

	return url, merkle, nil
}

type ImagesManifest struct {
	Version  string        `json:"version"`
	Contents ImagesContent `json:"contents"`
}

func (i *ImagesManifest) Clone() ImagesManifest {
	partitions := []ImagePartition{}
	for _, p := range i.Contents.Partitions {
		partitions = append(partitions, p)
	}

	firmware := []ImageFirmware{}
	for _, f := range i.Contents.Firmware {
		firmware = append(firmware, f)
	}

	return ImagesManifest{
		Version: i.Version,
		Contents: ImagesContent{
			Partitions: partitions,
			Firmware:   firmware,
		},
	}
}

func (i *ImagesManifest) Rehost(newHostName string) error {
	for idx, p := range i.Contents.Partitions {
		u, err := url.Parse(p.Url)
		if err != nil {
			return err
		}

		u.Host = newHostName
		p.Url = u.String()

		i.Contents.Partitions[idx] = p
	}

	for idx, f := range i.Contents.Firmware {
		u, err := url.Parse(f.Url)
		if err != nil {
			return err
		}

		u.Host = newHostName
		f.Url = u.String()

		i.Contents.Firmware[idx] = f
	}

	return nil
}

func (i *ImagesManifest) GetPartition(slot string, typ string) (*url.URL, build.MerkleRoot, error) {
	found := false
	var partition ImagePartition
	for _, p := range i.Contents.Partitions {
		if p.Slot == slot && p.Type == typ {
			found = true
			partition = p
			break
		}
	}
	if !found {
		return nil, build.MerkleRoot{}, fmt.Errorf("missing entry for zbi")
	}

	return ParsePackageUrl(partition.Url)
}

func (i *ImagesManifest) SetPartition(slot string, typ string, url string, path string) error {
	fi, err := os.Stat(path)
	if err != nil {
		return err
	}
	size := fi.Size()

	hash, err := Sha256File(path)
	if err != nil {
		return err
	}

	for idx := 0; idx < len(i.Contents.Partitions); idx++ {
		p := &i.Contents.Partitions[idx]

		if p.Slot == slot && p.Type == typ {
			p.Url = url
			p.Size = size
			p.Hash = hash
			return nil
		}
	}

	return fmt.Errorf("could not find partition %s %s", slot, typ)
}

type ImagesContent struct {
	Partitions []ImagePartition `json:"partitions"`
	Firmware   []ImageFirmware  `json:"firmware"`
}

type ImagePartition struct {
	Slot string `json:"slot"`
	Type string `json:"type"`
	Size int64  `json:"size"`
	Hash string `json:"hash"`
	Url  string `json:"url"`
}

type ImageFirmware struct {
	Type string `json:"type"`
	Size int64  `json:"size"`
	Hash string `json:"hash"`
	Url  string `json:"url"`
}

func AtomicallyWriteFile(path string, mode os.FileMode, writeFileFunc func(*os.File) error) error {
	dir := filepath.Dir(path)
	basename := filepath.Base(path)

	tmpfile, err := os.CreateTemp(dir, basename)
	if err != nil {
		return err
	}
	defer func() {
		if tmpfile != nil {
			tmpfile.Close()
			os.Remove(tmpfile.Name())
		}
	}()

	if err = writeFileFunc(tmpfile); err != nil {
		return err
	}

	if err = os.Chmod(tmpfile.Name(), mode); err != nil {
		return err
	}

	// Now that we've written the file, do an atomic swap of the filename into place.
	if err := os.Rename(tmpfile.Name(), path); err != nil {
		return err
	}
	if err := tmpfile.Close(); err != nil {
		return err
	}
	tmpfile = nil

	return nil
}

// RunWithTimeout runs a closure to completion, or returns an error if it times
// out.
func RunWithTimeout(ctx context.Context, timeout time.Duration, f func() error) error {
	return RunWithDeadline(ctx, time.Now().Add(timeout), f)
}

// RunWithDeadline runs a closure to runs the closure in a goroutine
func RunWithDeadline(ctx context.Context, deadline time.Time, f func() error) error {
	ctx, cancel := context.WithDeadline(ctx, deadline)
	defer cancel()

	ch := make(chan error, 1)
	go func() {
		ch <- f()
	}()

	select {
	case err := <-ch:
		return err
	case <-ctx.Done():
		return fmt.Errorf("Function timed out: %w", ctx.Err())
	}
}

func ValidatePath(path string) error {
	if path != "" {
		if _, err := os.Stat(path); err != nil {
			if os.IsNotExist(err) {
				return fmt.Errorf("no such file or directory exists: %q", path)
			} else {
				return fmt.Errorf("unexpected error reading %q: %v", path, err)
			}
		}
	}

	return nil
}

func AddSuffixToPackageName(packagePath string, suffix string) string {
	before, after, ok := strings.Cut(packagePath, "/")
	if ok {
		return fmt.Sprintf("%s_%s/%s", before, suffix, after)
	} else {
		return fmt.Sprintf("%s_%s", before, suffix)
	}
}
