// Copyright 2023 The Go 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 darwinpkg encodes the process of building a macOS PKG
// installer from the given Go toolchain .tar.gz binary archive.
package darwinpkg

import (
	"bytes"
	"context"
	"embed"
	"errors"
	"fmt"
	"io"
	"io/fs"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"text/template"

	"golang.org/x/build/internal/untar"
)

// InstallerOptions holds options for constructing the installer.
type InstallerOptions struct {
	GOARCH string // The target GOARCH.
	// MinMacOSVersion is the minimum required system.version.ProductVersion.
	// For example, "11" for macOS 11 Big Sur, "10.15" for macOS 10.15 Catalina, etc.
	MinMacOSVersion string
}

// ConstructInstaller constructs an installer for the provided Go toolchain .tar.gz
// binary archive using workDir as a working directory, and returns the output path.
//
// It's intended to run on a macOS system, with Xcode tools available in $PATH.
func ConstructInstaller(_ context.Context, workDir, tgzPath string, opt InstallerOptions) (pkgPath string, _ error) {
	var errs []error
	for _, dep := range [...]string{"pkgbuild", "productbuild"} {
		if _, err := exec.LookPath(dep); err != nil {
			errs = append(errs, fmt.Errorf("dependency %q is not in PATH", dep))
		}
	}
	if opt.GOARCH == "" {
		errs = append(errs, fmt.Errorf("GOARCH is empty"))
	}
	if opt.MinMacOSVersion == "" {
		errs = append(errs, fmt.Errorf("MinMacOSVersion is empty"))
	}
	if err := errors.Join(errs...); err != nil {
		return "", err
	}

	oldDir, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	if err := os.Chdir(workDir); err != nil {
		panic(err)
	}
	defer func() {
		if err := os.Chdir(oldDir); err != nil {
			panic(err)
		}
	}()

	fmt.Println("Building inner .pkg with pkgbuild.")
	run("mkdir", "pkg-intermediate")
	putTar(tgzPath, "pkg-root/usr/local")
	put("/usr/local/go/bin\n", "pkg-root/etc/paths.d/go", 0644)
	put(`#!/bin/bash

GOROOT=/usr/local/go
echo "Removing previous installation"
if [ -d $GOROOT ]; then
	rm -r $GOROOT
fi
`, "pkg-scripts/preinstall", 0755)
	put(`#!/bin/bash

GOROOT=/usr/local/go
echo "Fixing permissions"
cd $GOROOT
find . -exec chmod ugo+r \{\} \;
find bin -exec chmod ugo+rx \{\} \;
find . -type d -exec chmod ugo+rx \{\} \;
chmod o-w .
`, "pkg-scripts/postinstall", 0755)
	version := readVERSION("pkg-root/usr/local/go")
	run("pkgbuild",
		"--identifier=org.golang.go",
		"--version", version,
		"--scripts=pkg-scripts",
		"--root=pkg-root",
		"pkg-intermediate/org.golang.go.pkg",
	)

	fmt.Println("\nBuilding outer .pkg with productbuild.")
	run("mkdir", "pkg-out")
	bg, err := darwinPKGBackground(opt.GOARCH)
	if err != nil {
		log.Fatalln("darwinPKGBackground:", err)
	}
	put(string(bg), "pkg-resources/background.png", 0644)
	var buf bytes.Buffer
	distData := darwinDistData{
		HostArchs: map[string]string{"amd64": "x86_64", "arm64": "arm64"}[opt.GOARCH],
		MinOS:     opt.MinMacOSVersion,
	}
	if err := darwinDistTmpl.ExecuteTemplate(&buf, "dist.xml", distData); err != nil {
		log.Fatalln("darwinDistTmpl.ExecuteTemplate:", err)
	}
	put(buf.String(), "pkg-distribution", 0644)
	run("productbuild",
		"--distribution=pkg-distribution",
		"--resources=pkg-resources",
		"--package-path=pkg-intermediate",
		"pkg-out/"+version+"-unsigned.pkg",
	)

	return filepath.Join(workDir, "pkg-out", version+"-unsigned.pkg"), nil
}

//go:embed _data
var darwinPKGData embed.FS

func darwinPKGBackground(goarch string) ([]byte, error) {
	switch goarch {
	case "arm64":
		return darwinPKGData.ReadFile("_data/blue-bg.png")
	case "amd64":
		return darwinPKGData.ReadFile("_data/brown-bg.png")
	default:
		return nil, fmt.Errorf("no background for GOARCH %q", goarch)
	}
}

var darwinDistTmpl = template.Must(template.New("").ParseFS(darwinPKGData, "_data/dist.xml"))

type darwinDistData struct {
	HostArchs string // hostArchitectures option value.
	MinOS     string // Minimum required system.version.ProductVersion.
}

func put(content, dst string, perm fs.FileMode) {
	err := os.MkdirAll(filepath.Dir(dst), 0755)
	if err != nil {
		panic(err)
	}
	f, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
	if err != nil {
		panic(err)
	}
	_, err = io.WriteString(f, content)
	if err != nil {
		panic(err)
	}
	err = f.Close()
	if err != nil {
		panic(err)
	}
}

func putTar(tgz, dir string) {
	f, err := os.Open(tgz)
	if err != nil {
		panic(err)
	}
	err = untar.Untar(f, dir)
	if err != nil {
		panic(err)
	}
	err = f.Close()
	if err != nil {
		panic(err)
	}
}

// run runs the command and requires that it succeeds.
// If not, it logs the failure and exits with a non-zero code.
// It prints the command line.
func run(name string, args ...string) {
	fmt.Printf("$ %s %s\n", name, strings.Join(args, " "))
	out, err := exec.Command(name, args...).CombinedOutput()
	if err != nil {
		log.Fatalf("command failed: %v\n%s", err, out)
	}
}

// readVERSION reads the VERSION file and
// returns the first line of the file, the Go version.
func readVERSION(goroot string) (version string) {
	b, err := os.ReadFile(filepath.Join(goroot, "VERSION"))
	if err != nil {
		panic(err)
	}
	version, _, _ = strings.Cut(string(b), "\n")
	return version
}
