// extract_puppeteer_screenshots extracts Puppeteer screenshots into a user-specified directory.
//
// Usage:
//
//     $ bazel run //:extract_puppeteer_screenshots -- --output_dir=<output directory>
//
// Under Bazel, Puppeteer tests save screenshots inside $TEST_UNDECLARED_OUTPUTS_DIR, which is set
// by the "bazel test" command. Screenshots, and any other undeclared outputs of a test, can be
// found under //_bazel_testlogs bundled as a single .zip file per test target.
//
// For example, if we run a Puppeteer test with "bazel test //my_app:puppeteer_test", then any
// screenshots will be found inside //_bazel_testlogs/my_app/puppeteer_test/test.outputs/outputs.zip.
//
// See https://docs.bazel.build/versions/master/test-encyclopedia.html#initial-conditions to learn
// more about undeclared test outputs.
package main

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

	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
)

var (
	outputDir = flag.String("output_dir", "", "Directory inside which to extract screenshots.")

	outputDirAbsPath string
)

func main() {
	flag.Parse()
	if *outputDir == "" {
		failf("Flag --output_dir is required.\n")
	}

	// If running via "bazel run", change into the directory where Bazel was invoked. This is
	// necessary to correctly compute the absolute path of the output directory.
	if os.Getenv("BUILD_WORKING_DIRECTORY") != "" {
		if err := os.Chdir(os.Getenv("BUILD_WORKING_DIRECTORY")); err != nil {
			sklog.Fatal(err)
		}
	}

	// Validate and compute the absolute path of the output directory.
	var err error
	if outputDirAbsPath, err = filepath.Abs(*outputDir); err != nil {
		failf("Invalid path: \"%s\"\n", *outputDir)
	}
	if _, err := os.Stat(*outputDir); os.IsNotExist(err) {
		failf("Directory \"%s\" does not exist.\n", *outputDir)
	}

	// If running via "bazel run", change into the workspace root directory (i.e. where the WORKSPACE
	// file is located). If not, we assume that the current working directory is the workspace root.
	if os.Getenv("BUILD_WORKSPACE_DIRECTORY") != "" {
		if err := os.Chdir(os.Getenv("BUILD_WORKSPACE_DIRECTORY")); err != nil {
			sklog.Fatal(err)
		}
	}

	// Resolve the //_bazel_testlogs symlink. Necessary because filepath.Walk() ignores symlinks.
	bazelTestlogsDir, err := filepath.EvalSymlinks("_bazel_testlogs")
	if err != nil {
		sklog.Fatal(err)
	}

	// Find all outputs.zip files under //_bazel_testlogs, which contain the undeclared outputs
	// produced by all tests.
	var allOutputsZipPaths []string
	if err := filepath.Walk(bazelTestlogsDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return skerr.Wrap(err)
		}
		if strings.HasSuffix(path, "/test.outputs/outputs.zip") {
			allOutputsZipPaths = append(allOutputsZipPaths, path)
		}
		return nil
	}); err != nil {
		sklog.Fatal(err)
	}

	// Inspect each outputs.zip file for Puppeteer screenshots. Extract them into the output directory
	// if any are found.
	for _, path := range allOutputsZipPaths {
		if err := extractPuppeteerScreenshotsFromOutputsZip(path); err != nil {
			sklog.Fatal(err)
		}
	}
}

// failf prints a message to sterr and exits with a non-zero exit code.
func failf(msg string, args ...interface{}) {
	if _, err := fmt.Fprintf(os.Stderr, msg, args...); err != nil {
		sklog.Fatal(err)
	}
	os.Exit(1)
}

// extractPuppeteerScreenshotsFromOutputsZip inspects an outputs.zip file looking for screenshots
// taken by a Puppeteer test, and extracts the screenshots inside the output directory if any are
// found.
//
// This function makes the following assumptions:
//
//   - All screenshots produced by a Puppeteer tests will be found inside a
//     "puppeteer-test-screenshots" directory within the test's outputs.zip file.
//   - All screenshots are PNG files (*.png)
//   - Puppeteer tests are the only tests in our codebase that produce undeclared outputs following
//     the above conventions.
//
// An alternative approach is to find all Puppeteer tests via a Bazel query (e.g.
// "bazel query 'attr(generator_function, sk_element_puppeteer_test, //...)'"), but this can be
// slow. Inspecting all outputs.zip files inside the //_bazel_testlogs directory is much faster.
func extractPuppeteerScreenshotsFromOutputsZip(zipFilePath string) error {
	// Open the ZIP archive.
	zipFile, err := zip.OpenReader(zipFilePath)
	if err != nil {
		return skerr.Wrap(err)
	}
	defer util.Close(zipFile)

	// Iterate over all files inside the ZIP archive.
	for _, file := range zipFile.File {
		// Skip if the file is not a Puppeteer screenshot.
		dir, screenshotFileName := filepath.Split(file.Name)
		if dir != "puppeteer-test-screenshots/" || !strings.HasSuffix(screenshotFileName, ".png") {
			continue
		}

		// Extract screenshot into the output directory.
		outputFileName := filepath.Join(outputDirAbsPath, screenshotFileName)
		if err := extractFileFromZipArchive(file, outputFileName); err != nil {
			return skerr.Wrap(err)
		}
		fmt.Printf("Extracted screenshot: %s\n", outputFileName)
	}

	return nil
}

// extractFileFromZipArchive extracts a file inside a ZIP archive, and saves it to the outputPath.
func extractFileFromZipArchive(zippedFile *zip.File, outputPath string) error {
	// Open the file inside the ZIP archive.
	zippedFileReader, err := zippedFile.Open()
	if err != nil {
		return skerr.Wrap(err)
	}
	defer util.Close(zippedFileReader)

	// Save it to disk.
	if err := util.WithWriteFile(outputPath, func(w io.Writer) error {
		if _, err := io.Copy(w, zippedFileReader); err != nil {
			return skerr.Wrap(err)
		}
		return nil
	}); err != nil {
		return skerr.Wrap(err)
	}

	return nil
}
