// Copyright 2019 The Fuchsia 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 reads a recipe spec by creating a checkout of the specified repository,
// according to the current build input. Clients should run this in the directory where
// they want the repository to be checked out. The spec is printed to stdout on success.
// On failure, a non-zero exit code is returned.
//
// This MUST be called after the input Buildbucket build has been resolved to contain a
// Gitiles commit. The build.proto object written to stdin must be base64 encoded to avoid
// logging invalid UTF-8 characters which breaks logdog.
//
// The exit codes of this program are as follows:
// 0: Ok
// 1: Unexpected fatal error
// 2: The spec file was not found
package main

import (
	"context"
	"encoding/base64"
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/url"
	"os"

	"github.com/golang/protobuf/proto"

	buildbucketpb "go.chromium.org/luci/buildbucket/proto"
	"go.fuchsia.dev/infra/cmd/build_init/checkout"
)

const (
	// The directory containing specs in the spec repository.
	defaultSpecDir = "infra/config/generated"
	defaultGitPath = "/usr/bin/git"
)

// Exit codes
const (
	ExitOk           = 0
	ExitFatal        = 1
	ExitFileNotFound = 2
)

// Command line flags.
var (
	// The path to the spec file within the repository.
	specPath string

	// The URL of the spec repository.
	specRemote string

	// The git ref of the specRemote to fetch the spec from.
	specRef string
)

// Variables derived from user input.
var (
	// The URL to the spec repository.
	specRepoURL *url.URL

	// The build.proto object read from stdin.
	build *buildbucketpb.Build
)

func init() {
	// Required
	flag.StringVar(&specRemote, "spec_remote", "", "The URL of the spec repository")
	flag.StringVar(&specPath, "spec_path", "", "The path to the spec file relative to the repo root")
	flag.StringVar(&specRef, "spec_ref", "HEAD", "The ref to fetch the spec from. The default is HEAD")
}

func main() {
	flag.Parse()
	if err := validateInputs(); err != nil {
		log.Fatal(err)
	}
	os.Exit(Execute(context.Background(), build, specRepoURL, specPath, specRef))
}

func validateInputs() (err error) {
	if specRemote == "" {
		return errors.New("missing -spec_remote")
	}

	specRepoURL, err = url.Parse(specRemote)
	if err != nil {
		return fmt.Errorf("invalid URL for -spec_remote: %v", err)
	}

	build, err = loadBuildProto(os.Stdin)
	if err != nil {
		return fmt.Errorf("failed to read build.proto: %v", err)
	}
	if err := validateBuild(*build); err != nil {
		return fmt.Errorf("invalid build message: %v", err)
	}

	if specPath == "" {
		return errors.New("must specify -spec_path")
	}

	return nil
}

func validateBuild(build buildbucketpb.Build) error {
	if build.Input == nil {
		return errors.New("build has no input")
	}
	if build.Input.GitilesCommit == nil {
		return errors.New("build input has no Gitiles commit")
	}
	if build.Builder == nil {
		return errors.New("input build has no builder information")
	}
	if build.Builder.Bucket == "" {
		return errors.New("input build's builder has no bucket")
	}
	if build.Builder.Builder == "" {
		return errors.New("input build's builder name is empty")
	}
	return nil
}

// Execute runs the program. Public for testing.
func Execute(ctx context.Context, build *buildbucketpb.Build, specRepoURL *url.URL, specPath string, specRef string) (code int) {
	if err := checkout.Checkout(*build.Input, *specRepoURL, specRef); err != nil {
		log.Printf("failed to checkout %s: %v", specRepoURL.String(), err)
		return ExitFatal
	}

	if _, err := os.Stat(specPath); os.IsNotExist(err) {
		log.Printf("file not found %v", specPath)
		return ExitFileNotFound
	}
	fd, err := os.Open(specPath)
	if err != nil {
		log.Printf("failed to open file %v: %v", specPath, err)
		return ExitFatal
	}
	defer fd.Close()
	if _, err := io.Copy(os.Stdout, fd); err != nil {
		log.Printf("failed to write file to output: %v", err)
		return ExitFatal
	}

	return ExitOk
}

// Loads a buildbucketpb.Build message from the given reader. The input must be base64.
func loadBuildProto(r io.Reader) (*buildbucketpb.Build, error) {
	build := new(buildbucketpb.Build)
	decoder := base64.NewDecoder(base64.StdEncoding, r)
	bytes, err := ioutil.ReadAll(decoder)
	if err != nil {
		return nil, fmt.Errorf("failed to read build.proto: %v", err)
	}
	if err := proto.Unmarshal(bytes, build); err != nil {
		return nil, fmt.Errorf("failed to unmarshal build.proto: %v", err)
	}
	return build, nil
}
