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

// Command inithelper manages services for a variety of platforms and init
// systems, such as upstart, systemd etc.
package main

// TODO(caprita): The separation of responsibilities between root/non-root code
// can be shifted away from root a bit more, by having the init daemon files
// created as non-root and root just installs files and runs a specific set of
// commands.  Figure out if worth it.  Also consider combining with suidhelper.
// For now they're separate since we don't always need both at the same time.

// TODO(caprita): Add unit test.

import (
	"bytes"
	"flag"
	"fmt"
	"os"

	"v.io/x/ref/services/device/internal/sysinit"
)

func usage() {
	const usage = `Usage:
%s [flags] [command]

 Flags:
%s
 Command:
  print: prints the file that would be installed
  install: installs the service
  uninstall: uninstalls the service
  start: starts the service
  stop: stops the service
`
	var flagDefaults bytes.Buffer
	flag.CommandLine.SetOutput(&flagDefaults)
	flag.CommandLine.PrintDefaults()
	flag.CommandLine.SetOutput(nil)
	fmt.Fprintf(os.Stderr, usage, os.Args[0], flagDefaults.String())
}

func main() {
	fmt.Fprintln(os.Stderr, os.Args)
	if os.Geteuid() != 0 && os.Getuid() != 0 {
		fmt.Fprintln(os.Stderr, "uid is ", os.Getuid(), ", effective uid is ", os.Geteuid())
		fmt.Fprintln(os.Stderr, "inithelper is not root. Is your filesystem mounted with nosuid?")
		os.Exit(1)
	}

	flag.Usage = usage
	sdFlag := flag.String("service_description", "", "File containing a JSON-encoded sysinit.ServiceDescription object.")
	systemFlag := flag.String("system", sysinit.InitSystem(), "System label, to select the appropriate sysinit mechanism.")
	flag.Parse()
	if *sdFlag == "" {
		fmt.Fprintf(os.Stderr, "--service_description must be set.\n")
		flag.Usage()
		os.Exit(1)
	}
	if *systemFlag == "" {
		fmt.Fprintf(os.Stderr, "--system must be set.\n")
		flag.Usage()
		os.Exit(1)
	}
	var sd sysinit.ServiceDescription
	if err := sd.LoadFrom(*sdFlag); err != nil {
		fmt.Fprintf(os.Stderr, "LoadFrom(%v) failed: %v\n", *sdFlag, err)
		os.Exit(2)
	}
	si := sysinit.New(*systemFlag, &sd)
	args := flag.Args()
	if len(args) != 1 {
		fmt.Fprintf(os.Stderr, "Command must be specified.\n")
		flag.Usage()
		os.Exit(1)
	}
	switch args[0] {
	case "print":
		if err := si.Print(); err != nil {
			fmt.Fprintf(os.Stderr, "Failed to print %v: %s\n", si, err)
			os.Exit(2)
		}
	case "install":
		if err := si.Install(); err != nil {
			fmt.Fprintf(os.Stderr, "Failed to install %v: %s\n", si, err)
			os.Exit(2)
		}
	case "uninstall":
		if err := si.Uninstall(); err != nil {
			fmt.Fprintf(os.Stderr, "Failed to uninstall %v: %s\n", si, err)
			os.Exit(2)
		}
	case "start":
		if err := si.Start(); err != nil {
			fmt.Fprintf(os.Stderr, "Failed to start %v: %s\n", si, err)
			os.Exit(2)
		}
	case "stop":
		if err := si.Stop(); err != nil {
			fmt.Fprintf(os.Stderr, "Failed to stop %v: %s\n", si, err)
			os.Exit(2)
		}
	default:
		fmt.Fprintf(os.Stderr, "Invalid command: %s\n", args[0])
		flag.Usage()
		os.Exit(1)
	}
}
