// Copyright 2015 The Vanadium 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 (
	"fmt"
	"go/build"
	"io/ioutil"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"time"

	"v.io/v23/context"
	vbuild "v.io/v23/services/build"
	"v.io/x/lib/cmdline"
)

var (
	flagArch string
	flagOS   string
)

func init() {
	cmdBuild.Flags.StringVar(&flagArch, "arch", runtime.GOARCH, "Target architecture.  The default is the value of runtime.GOARCH.")
	cmdBuild.Flags.Lookup("arch").DefValue = "<runtime.GOARCH>"
	cmdBuild.Flags.StringVar(&flagOS, "os", runtime.GOOS, "Target operating system.  The default is the value of runtime.GOOS.")
	cmdBuild.Flags.Lookup("os").DefValue = "<runtime.GOOS>"
}

var cmdRoot = &cmdline.Command{
	Name:  "build",
	Short: "sends commands to a Vanadium build server",
	Long: `
Command build sends commands to a Vanadium build server.
`,
	Children: []*cmdline.Command{cmdBuild},
}

// root returns a command that represents the root of the vanadium tool.
func root() *cmdline.Command {
	return cmdRoot
}

var cmdBuild = &cmdline.Command{
	Run:   runBuild,
	Name:  "build",
	Short: "Build vanadium Go packages",
	Long: `
Build vanadium Go packages using a remote build server. The command collects all
source code files that are not part of the Go standard library that the target
packages depend on, sends them to a build server, and receives the built
binaries.
`,
	ArgsName: "<name> <packages>",
	ArgsLong: `
<name> is a vanadium object name of a build server <packages> is a list of
packages to build, specified as arguments for each command. The format is
similar to the go tool.  In its simplest form each package is an import path;
e.g. "v.io/x/ref/services/build/build". A package that ends with "..." does a
wildcard match against all packages with that prefix.
`,
}

// TODO(jsimsa): Add support for importing (and remotely building)
// packages from multiple package source root GOPATH directories with
// identical names.
func importPackages(paths []string, pkgMap map[string]*build.Package) error {
	for _, path := range paths {
		recurse := false
		if strings.HasSuffix(path, "...") {
			recurse = true
			path = strings.TrimSuffix(path, "...")
		}
		if _, exists := pkgMap[path]; !exists {
			srcDir, mode := "", build.ImportMode(0)
			pkg, err := build.Import(path, srcDir, mode)
			if err != nil {
				// "C" is a pseudo-package for cgo: http://golang.org/cmd/cgo/
				// Do not attempt recursive imports.
				if pkg.ImportPath == "C" {
					continue
				}
				return fmt.Errorf("Import(%q,%q,%v) failed: %v", path, srcDir, mode, err)
			}
			if pkg.Goroot {
				continue
			}
			pkgMap[path] = pkg
			if err := importPackages(pkg.Imports, pkgMap); err != nil {
				return err
			}
		}
		if recurse {
			pkg := pkgMap[path]
			fis, err := ioutil.ReadDir(pkg.Dir)
			if err != nil {
				return fmt.Errorf("ReadDir(%v) failed: %v", pkg.Dir)
			}
			for _, fi := range fis {
				if fi.IsDir() {
					subPath := filepath.Join(path, fi.Name(), "...")
					if err := importPackages([]string{subPath}, pkgMap); err != nil {
						return err
					}
				}
			}
		}
	}
	return nil
}

func getSources(ctx *context.T, pkgMap map[string]*build.Package, errchan chan<- error) <-chan vbuild.File {
	sources := make(chan vbuild.File)
	go func() {
		defer close(sources)
		for _, pkg := range pkgMap {
			for _, files := range [][]string{pkg.CFiles, pkg.CgoFiles, pkg.GoFiles, pkg.SFiles} {
				for _, file := range files {
					path := filepath.Join(pkg.Dir, file)
					bytes, err := ioutil.ReadFile(path)
					if err != nil {
						errchan <- fmt.Errorf("ReadFile(%v) failed: %v", path, err)
						return
					}
					select {
					case sources <- vbuild.File{Contents: bytes, Name: filepath.Join(pkg.ImportPath, file)}:
					case <-ctx.Done():
						errchan <- fmt.Errorf("Get sources failed: %v", ctx.Err())
						return
					}
				}
			}
		}
		errchan <- nil
	}()
	return sources
}

func invokeBuild(ctx *context.T, name string, sources <-chan vbuild.File, errchan chan<- error) <-chan vbuild.File {
	binaries := make(chan vbuild.File)
	go func() {
		defer close(binaries)
		ctx, cancel := context.WithCancel(ctx)
		defer cancel()

		client := vbuild.BuilderClient(name)
		var arch vbuild.Architecture
		if err := arch.SetFromGoArch(flagArch); err != nil {
			errchan <- err
			return
		}
		var os vbuild.OperatingSystem
		if err := os.SetFromGoOS(flagOS); err != nil {
			errchan <- err
			return
		}
		stream, err := client.Build(ctx, arch, os)
		if err != nil {
			errchan <- fmt.Errorf("Build() failed: %v", err)
			return
		}
		sender := stream.SendStream()
		for source := range sources {
			if err := sender.Send(source); err != nil {
				errchan <- fmt.Errorf("Send() failed: %v", err)
				return
			}
		}
		if err := sender.Close(); err != nil {
			errchan <- fmt.Errorf("Close() failed: %v", err)
			return
		}
		iterator := stream.RecvStream()
		for iterator.Advance() {
			select {
			case binaries <- iterator.Value():
			case <-ctx.Done():
				errchan <- fmt.Errorf("Invoke build failed: %v", ctx.Err())
				return
			}
		}
		if err := iterator.Err(); err != nil {
			errchan <- fmt.Errorf("Advance() failed: %v", err)
			return
		}
		if out, err := stream.Finish(); err != nil {
			errchan <- fmt.Errorf("Finish() failed: (%v, %v)", string(out), err)
			return
		}
		errchan <- nil
	}()
	return binaries
}

func saveBinaries(ctx *context.T, prefix string, binaries <-chan vbuild.File, errchan chan<- error) {
	go func() {
		for binary := range binaries {
			select {
			case <-ctx.Done():
				errchan <- fmt.Errorf("Save binaries failed: %v", ctx.Err())
				return
			default:
			}
			path, perm := filepath.Join(prefix, filepath.Base(binary.Name)), os.FileMode(0755)
			if err := ioutil.WriteFile(path, binary.Contents, perm); err != nil {
				errchan <- fmt.Errorf("WriteFile(%v, %v) failed: %v", path, perm, err)
				return
			}
			fmt.Printf("Generated binary %v\n", path)
		}
		errchan <- nil
	}()
}

// runBuild identifies the source files needed to build the packages
// specified on command-line and then creates a pipeline that
// concurrently 1) reads the source files, 2) sends them to the build
// server and receives binaries from the build server, and 3) writes
// the binaries out to the disk.
func runBuild(command *cmdline.Command, args []string) error {
	name, paths := args[0], args[1:]
	pkgMap := map[string]*build.Package{}
	if err := importPackages(paths, pkgMap); err != nil {
		return err
	}
	errchan := make(chan error)
	defer close(errchan)

	ctx, ctxCancel := context.WithTimeout(gctx, time.Minute)
	defer ctxCancel()

	// Start all stages of the pipeline.
	sources := getSources(ctx, pkgMap, errchan)
	binaries := invokeBuild(ctx, name, sources, errchan)
	saveBinaries(ctx, os.TempDir(), binaries, errchan)
	// Wait for all stages of the pipeline to terminate.
	errors, numStages := []error{}, 3
	for i := 0; i < numStages; i++ {
		if err := <-errchan; err != nil {
			errors = append(errors, err)
			ctxCancel()
		}
	}
	if len(errors) != 0 {
		return fmt.Errorf("build failed(%v)", errors)
	}
	return nil
}
