/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
package main

// Example use:
//   git clone https://skia.googlesource.com/skia.git
//   cd skia
//   SKIA=$PWD
//   cd experimental/fiddle
//   go get github.com/skia-dev/glog
//   go get go.skia.org/infra/go/util
//   go build fiddler.go
//   # compile prerequisites
//   ./fiddler "$SKIA"
//   # compile and run a fiddle
//   ./fiddler "$SKIA" draw.cpp | ./parse-fiddle-output
//   # compile and run a different fiddle
//   ./fiddler "$SKIA" ANOTHER_FIDDLE.cpp | ./parse-fiddle-output

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"syscall"

	"github.com/skia-dev/glog"
	"go.skia.org/infra/go/util"
)

func setResourceLimits() error {
	const maximumTimeInSeconds = 5
	limit := syscall.Rlimit{maximumTimeInSeconds, maximumTimeInSeconds}
	if err := syscall.Setrlimit(syscall.RLIMIT_CPU, &limit); err != nil {
		return err
	}
	const maximumMemoryInBytes = 1 << 28
	limit = syscall.Rlimit{maximumMemoryInBytes, maximumMemoryInBytes}
	return syscall.Setrlimit(syscall.RLIMIT_AS, &limit)
}

// execCommand runs command and returns an error if it fails.  If there is no
// error, all output is discarded.
func execCommand(input io.Reader, dir string, name string, arg ...string) error {
	var buffer bytes.Buffer
	cmd := exec.Command(name, arg...)
	cmd.Dir = dir
	cmd.Stdout = &buffer
	cmd.Stderr = &buffer
	cmd.Stdin = input
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("execution failed:\n\n%s\n[%v]", buffer.String(), err)
	}
	return nil
}

func compileArgs(skiaSrc string) string {
	return "@" + path.Join(skiaSrc, "cmake", "skia_compile_arguments.txt")
}

func linkArgs(skiaSrc string) string {
	return "@" + path.Join(skiaSrc, "cmake", "skia_link_arguments.txt")
}

// fiddler compiles the input, links against skia, and runs the executable.
// @param skiaSrc: the base directory of the Skia repository
// @param inputReader: C++ fiddle source
// @param output: stdout of executable sent here
// @param tempDir: where to place the compiled executable
func fiddler(skiaSrc string, inputReader io.Reader, output io.Writer, tempDir string) error {
	binarypath := path.Join(tempDir, "fiddle")
	fiddle_dir := path.Join(skiaSrc, "experimental", "fiddle")
	if err := execCommand(inputReader, fiddle_dir,
		"c++",
		compileArgs(skiaSrc),
		"-I", fiddle_dir,
		"-o", binarypath,
		"-x", "c++", "-", "-x", "none",
		"fiddle_main.o",
		"-lOSMesa",
		linkArgs(skiaSrc),
	); err != nil {
		return err
	}
	var buffer bytes.Buffer
	runCmd := exec.Cmd{Path: binarypath, Stdout: output, Stderr: &buffer}
	if err := runCmd.Run(); err != nil {
		return fmt.Errorf("execution failed:\n\n%s\n[%v]", buffer.String(), err)
	}
	return nil
}

// Compile Skia library and fiddle_main.cpp
// @param skiaSrc: the base directory of the Skia repository.
func fiddlerPrerequisites(skiaSrc string) error {
	cmakeDir := path.Join(skiaSrc, "cmake")
	if err := execCommand(nil, cmakeDir, "cmake", "-G", "Ninja", "."); err != nil {
		return err
	}
	if err := execCommand(nil, cmakeDir, "ninja", "skia"); err != nil {
		return err
	}
	fiddle_dir := path.Join(skiaSrc, "experimental", "fiddle")
	if err := execCommand(nil, fiddle_dir, "c++", compileArgs(skiaSrc),
		"fiddle_main.h"); err != nil {
		return err
	}
	return execCommand(nil, fiddle_dir, "c++", compileArgs(skiaSrc),
		"-c", "-o", "fiddle_main.o", "fiddle_main.cpp")
}

func main() {
	if len(os.Args) < 2 {
		glog.Fatalf("usage: %s SKIA_SRC_PATH [PATH_TO_DRAW.CPP]", os.Args[0])
	}
	skiaSrc := os.Args[1]
	if len(os.Args) < 3 {
		// execCommand(nil, skiaSrc, "git", "fetch")
		// execCommand(nil, skiaSrc, "git", "checkout", "origin/master")
		if err := fiddlerPrerequisites(skiaSrc); err != nil {
			glog.Fatal(err)
		}
	} else {
		if err := setResourceLimits(); err != nil {
			glog.Fatal(err)
		}
		tempDir, err := ioutil.TempDir("", "fiddle_")
		if err != nil {
			glog.Fatal(err)
		}
		defer func() {
			err = os.RemoveAll(tempDir)
			if err != nil {
				glog.Fatalf("os.RemoveAll(tempDir) failed: %v", err)
			}
		}()
		if os.Args[2] == "-" {
			if err := fiddler(skiaSrc, os.Stdin, os.Stdout, tempDir); err != nil {
				glog.Fatal(err)
			}
		} else {
			inputFile, err := os.Open(os.Args[2])
			if err != nil {
				glog.Fatalf("unable to open \"%s\": %v", os.Args[2], err)
			}
			util.Close(inputFile)
			if err = fiddler(skiaSrc, inputFile, os.Stdout, tempDir); err != nil {
				glog.Fatal(err)
			}
		}
	}
}
