// Copyright 2017 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.

// This file contains a program that reads cobalt configuration in a YAML format
// and outputs it as a CobaltConfig serialized protocol buffer.

package main

import (
	"config"
	"config_parser"
	"config_validator"
	"flag"
	"fmt"
	"github.com/golang/glog"
	"io"
	"io/ioutil"
	"os"
	"strings"
	"time"
)

var (
	repoUrl         = flag.String("repo_url", "", "URL of the repository containing the config. Exactly one of 'repo_url', 'config_file' or 'config_dir' must be specified.")
	configDir       = flag.String("config_dir", "", "Directory containing the config. Exactly one of 'repo_url', 'config_file' or 'config_dir' must be specified.")
	configFile      = flag.String("config_file", "", "File containing the config for a single project. Exactly one of 'repo_url', 'config_file' or 'config_dir' must be specified.")
	outFile         = flag.String("output_file", "", "File to which the serialized config should be written. Defaults to stdout.")
	checkOnly       = flag.Bool("check_only", false, "Only check that the configuration is valid.")
	skipValidation  = flag.Bool("skip_validation", false, "Skip validating the config, write it no matter what.")
	gitTimeoutSec   = flag.Int64("git_timeout", 60, "How many seconds should I wait on git commands?")
	customerId      = flag.Int64("customer_id", -1, "Customer Id for the config to be read. Must be set if and only if 'config_file' is set.")
	projectId       = flag.Int64("project_id", -1, "Project Id for the config to be read. Must be set if and only if 'config_file' is set.")
	outFormat       = flag.String("out_format", "bin", "Specifies the output format. Supports 'bin' (serialized proto), 'b64' (serialized proto to base 64) and 'cpp' (ta C++ file containing a variable with a base64-encoded serialized proto.)")
	varName         = flag.String("var_name", "config", "When using the 'cpp' output format, this will specify the variable name to be used in the output.")
	namespace       = flag.String("namespace", "", "When using the 'cpp' output format, this will specify the comma-separated namespace within which the config variable must be places.")
	listConfigFiles = flag.Bool("list_config_files", false, "List the files that comprise the configuration of Cobalt. This should be used in conjunction with the 'config_dir' flag only.")
)

func main() {
	flag.Parse()

	if (*repoUrl == "") == (*configDir == "") == (*configFile == "") {
		glog.Exit("Exactly one of 'repo_url', 'config_file' and 'config_dir' must be set.")
	}

	if *configFile == "" && (*customerId >= 0 || *projectId >= 0) {
		glog.Exit("'customer_id' and 'project_id' must be set if and only if 'config_file' is set.")
	}

	if *configFile != "" && (*customerId < 0 || *projectId < 0) {
		glog.Exit("If 'config_file' is set, both 'customer_id' and 'project_id' must be set.")
	}

	if *outFile != "" && *checkOnly {
		glog.Exit("'output_file' does not make sense if 'check_only' is set.")
	}

	if *listConfigFiles && *configDir == "" {
		glog.Exit("'list_config_files' is only compatible with 'config_dir' being set.")
	}

	var configLocation string
	if *repoUrl != "" {
		configLocation = *repoUrl
	} else if *configFile != "" {
		configLocation = *configFile
	} else {
		configLocation = *configDir
	}

	if *listConfigFiles {
		files, err := config_parser.GetConfigFilesListFromConfigDir(configLocation)
		if err != nil {
			glog.Exit(err)
		}

		fmt.Println(strings.Join(files, "\n"))
		os.Exit(0)
	}

	var outputFormatter config_parser.OutputFormatter
	switch *outFormat {
	case "bin":
		outputFormatter = config_parser.BinaryOutput
	case "b64":
		outputFormatter = config_parser.Base64Output
	case "cpp":
		namespaceList := []string{}
		if *namespace != "" {
			namespaceList = strings.Split(*namespace, ",")
		}
		outputFormatter = config_parser.CppOutputFactory(*varName, namespaceList, configLocation)
	default:
		glog.Exitf("'%v' is an invalid out_format parameter. 'bin', 'b64' and 'cpp' are the only valid values for out_format.", *outFormat)
	}

	// First, we parse the configuration from the specified location.
	var c config.CobaltConfig
	var err error
	if *repoUrl != "" {
		gitTimeout := time.Duration(*gitTimeoutSec) * time.Second
		c, err = config_parser.ReadConfigFromRepo(*repoUrl, gitTimeout)
	} else if *configFile != "" {
		c, err = config_parser.ReadConfigFromYaml(*configFile, uint32(*customerId), uint32(*projectId))
	} else {
		c, err = config_parser.ReadConfigFromDir(*configDir)
	}

	if err != nil {
		glog.Exit(err)
	}

	if !*skipValidation {
		if err = config_validator.ValidateConfig(&c); err != nil {
			glog.Exit(err)
		}
	}

	// Then, we serialize the configuration.
	configBytes, err := outputFormatter(&c)
	if err != nil {
		glog.Exit(err)
	}

	// Check that the output file is not empty.
	if len(configBytes) == 0 {
		glog.Exit("Output file is empty.")
	}

	// If no errors have occured yet and checkOnly was set, we are done.
	if *checkOnly {
		fmt.Printf("%s OK\n", configLocation)
		os.Exit(0)
	}

	// By default we print the output to stdout.
	w := os.Stdout

	// If an output file is specified, we write to a temporary file and then rename
	// the temporary file with the specified output file name.
	if *outFile != "" {
		if w, err = ioutil.TempFile("", "cobalt_config"); err != nil {
			glog.Exit(err)
		}
		defer w.Close()
	}

	_, err = w.Write(configBytes)
	if err != nil {
		glog.Exit(err)
	}

	if *outFile != "" {
		if err := os.Rename(w.Name(), *outFile); err != nil {
			// Rename doesn't work if /tmp is in a different partition. Attempting to copy.
			// TODO(azani): Look into doing this atomically.
			in, err := os.Open(w.Name())
			if err != nil {
				glog.Exit(err)
			}
			defer in.Close()

			out, err := os.Create(*outFile)
			if err != nil {
				glog.Exit(err)
			}
			defer out.Close()

			_, err = io.Copy(out, in)
			if err != nil {
				glog.Exit(err)
			}
		}
	}

	os.Exit(0)
}
