// Copyright 2019 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
package main

import (
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"

	"github.com/golang/protobuf/proto"
	"pigweed.dev/pw_target_runner"

	pb "pigweed.dev/proto/pw_target_runner/exec_server_config_pb"
)

// ServerOptions contains command-line options for the server.
type ServerOptions struct {
	// Path to a server configuration file.
	config string

	// Port on which to run.
	port int
}

// configureServerFromFile sets up the server with workers specifyed in a
// config file. The file contains a pw.target_runner.ServerConfig protobuf
// message in canonical protobuf text format.
func configureServerFromFile(s *pw_target_runner.Server, filepath string) error {
	content, err := ioutil.ReadFile(filepath)
	if err != nil {
		return err
	}

	var config pb.ServerConfig
	if err := proto.UnmarshalText(string(content), &config); err != nil {
		return err
	}

	log.Printf("Parsed server configuration from %s\n", filepath)

	runners := config.GetRunner()
	if runners == nil {
		return nil
	}

	// Create an exec worker for each of the runner messages listed in the
	// config and register them with the server.
	for i, runner := range runners {
		// Build the complete command for the worker from its "command"
		// and "args" fields in the proto message. The command is
		// required; arguments are optional.
		cmd := []string{runner.GetCommand()}
		if cmd[0] == "" {
			msg := fmt.Sprintf(
				"ServerConfig.runner[%d] does not specify a command; skipping\n", i)
			return errors.New(msg)
		}

		if args := runner.GetArgs(); args != nil {
			cmd = append(cmd, args...)
		}

		worker := pw_target_runner.NewExecDeviceRunner(i, cmd)
		s.RegisterWorker(worker)

		log.Printf(
			"Registered ExecDeviceRunner %s with args %v\n",
			cmd[0],
			cmd[1:])
	}

	return nil
}

func main() {
	configPtr := flag.String("config", "", "Path to server configuration file")
	portPtr := flag.Int("port", 8080, "Server port")

	flag.Parse()

	server := pw_target_runner.NewServer()

	if *configPtr != "" {
		if err := configureServerFromFile(server, *configPtr); err != nil {
			log.Fatalf("Failed to parse config file %s: %v", *configPtr, err)
		}
	}

	if err := server.Bind(*portPtr); err != nil {
		log.Fatal(err)
	}

	if err := server.Serve(); err != nil {
		log.Fatalf("Failed to start server: %v", err)
	}
}
