// Copyright 2021 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 main

import (
	"archive/zip"
	"flag"
	"fmt"
	"io"
	"os"
	"path/filepath"

	"golang.org/x/benchmarks/sweet/cli/bootstrap"
	"golang.org/x/benchmarks/sweet/common"
	"golang.org/x/benchmarks/sweet/common/log"
)

const (
	putUsage = `Uploads a new version of the benchmark assets to GCS.

Usage: %s put [flags]
`
)

type putCmd struct {
	auth           bootstrap.AuthOption
	force          bool
	cache          string
	bucket         string
	assetsDir      string
	assetsHashFile string
	version        string
}

func (*putCmd) Name() string { return "put" }
func (*putCmd) Synopsis() string {
	return "Uploads a new version of the benchmark assets."
}
func (*putCmd) PrintUsage(w io.Writer, base string) {
	fmt.Fprintf(w, putUsage, base)
}

func (c *putCmd) SetFlags(f *flag.FlagSet) {
	c.auth = bootstrap.AuthAppDefault
	f.Var(&c.auth, "auth", fmt.Sprintf("authentication method (options: %s)", authOpts(false)))
	f.BoolVar(&c.force, "force", false, "force upload even if assets for this version exist")
	f.StringVar(&c.version, "version", common.Version, "the version to upload assets for")
	f.StringVar(&c.bucket, "bucket", "go-sweet-assets", "GCS bucket to upload assets to")
	f.StringVar(&c.assetsDir, "assets-dir", "./assets", "assets directory to zip and upload")
	f.StringVar(&c.assetsHashFile, "assets-hash-file", "./assets.hash", "file containing assets SHA256 hashes")
}

func (c *putCmd) Run(_ []string) error {
	log.SetActivityLog(true)

	if err := bootstrap.ValidateVersion(c.version); err != nil {
		return err
	}

	log.Printf("Archiving, compressing, and uploading: %s", c.assetsDir)

	// Create storage writer for streaming.
	wc, err := bootstrap.NewStorageWriter(c.bucket, c.version, c.auth, c.force)
	if err != nil {
		return err
	}
	defer wc.Close()

	// Pass everything we write through a hash.
	hash := bootstrap.Hash()
	w := io.MultiWriter(wc, hash)

	// Write the archive.
	if err := createAssetsArchive(w, c.assetsDir, c.version); err != nil {
		return err
	}

	// Update hash file.
	log.Printf("Updating hash file...")
	return updateAssetsHash(bootstrap.CanonicalizeHash(hash), c.assetsHashFile, c.version, c.force)
}

func createAssetsArchive(w io.Writer, assetsDir, version string) (err error) {
	zw := zip.NewWriter(w)
	defer func() {
		if cerr := zw.Close(); cerr != nil && err == nil {
			err = fmt.Errorf("closing zip archive: %w", cerr)
		}
	}()
	return filepath.Walk(assetsDir, func(fpath string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		outPath, err := filepath.Rel(assetsDir, fpath)
		if err != nil {
			// By the guarantees of filepath.Walk, this shouldn't happen.
			panic(err)
		}
		if info.IsDir() {
			// Add a trailing slash to indicate we're creating a directory.
			_, err := zw.Create(outPath + "/")
			return err
		}
		if info.Mode()&os.ModeSymlink != 0 {
			return fmt.Errorf("encountered symlink %s: symbolic links are not supported in assets", fpath)
		}
		// Create a file in our zip archive for writing.
		fh := new(zip.FileHeader)
		fh.Name = outPath
		fh.Method = zip.Deflate
		fh.SetMode(info.Mode())
		zf, err := zw.CreateHeader(fh)
		if err != nil {
			return err
		}
		// Open the original file for reading.
		f, err := os.Open(fpath)
		if err != nil {
			return err
		}
		defer f.Close()

		// Copy data into the archive.
		_, err = io.Copy(zf, f)
		return err
	})
}

func updateAssetsHash(hash, hashfile, version string, force bool) error {
	vals, err := bootstrap.ReadHashesFile(hashfile)
	if err != nil {
		return err
	}
	if ok := vals.Put(version, hash, force); !ok {
		return fmt.Errorf("hash for this version already exists")
	}
	return vals.WriteToFile(hashfile)
}
