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

// TODO(cnicolaou): will need to figure out a simple of way of handling the
// different init systems supported by various versions of linux. One simple
// option is to just include them in the name when installing - e.g.
// simplevns-upstart.

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"
)

// action is a var so we can override it for testing.
var action = func(command, action, service string) error {
	cmd := exec.Command(command, action, service)
	if os.Geteuid() == 0 && os.Getuid() > 0 {
		// Set uid to root (e.g. when running from a suid binary),
		// otherwise initctl doesn't work.
		sysProcAttr := new(syscall.SysProcAttr)
		sysProcAttr.Credential = new(syscall.Credential)
		sysProcAttr.Credential.Gid = uint32(0)
		sysProcAttr.Credential.Uid = uint32(0)
		cmd.SysProcAttr = sysProcAttr
	}
	// Clear env.  In particular, initctl doesn't like USER being set to
	// something other than root.
	cmd.Env = []string{}
	output, err := cmd.CombinedOutput()
	fmt.Fprintf(os.Stderr, "%s output: for %s %s: %s\n", command, action, service, output)
	return err
}

var (
	upstartDir        = "/etc/init"
	upstartBin        = "/sbin/initctl"
	systemdDir        = "/lib/systemd/system" // This works for both rpi and edison (/usr/lib does not)
	systemdTmpFileDir = "/usr/lib/tmpfiles.d"
	dockerDir         = "/home/veyron/init"
)

// InitSystem attempts to determine what kind of init system is in use on
// the platform that it is run on. It recognises upstart and systemd by
// testing for the presence of the initctl and systemctl commands. upstart
// is tested for first and hence is preferred in the unlikely case that both
// are installed. Docker containers do not support upstart and systemd and
// for them we have our own init system that uses the daemon command to
// start/stop/respawn jobs.
func InitSystem() string {
	// NOTE(spetrovic): This check is kind of a hack. Ideally, we would
	// detect a docker system by looking at the "container=lxc" environment
	// variable.  However, we run sysinit during image creation, at which
	// point we're on a native system and this variable isn't set.
	if fi, err := os.Stat("/home/veyron/init"); err == nil && fi.Mode().IsDir() {
		return "docker"
	}
	if fi, err := os.Stat(upstartBin); err == nil {
		if (fi.Mode() & 0100) != 0 {
			return "upstart"
		}
	}

	if findSystemdSystemCtl() != "" {
		return "systemd"
	}

	return ""
}

// New returns the appropriate implementation of InstallSystemInit for the
// underlying system.
func New(system string, sd *ServiceDescription) InstallSystemInit {
	switch system {
	case "docker":
		return (*DockerService)(sd)
	case "upstart":
		return (*UpstartService)(sd)
	case "systemd":
		return (*SystemdService)(sd)
	default:
		return nil
	}
}

///////////////////////////////////////////////////////////////////////////////
// Upstart support

// See http://upstart.ubuntu.com/cookbook/ for info on upstart

// UpstartService is the implementation of InstallSystemInit interfacing with
// the Upstart system.
type UpstartService ServiceDescription

var upstartTemplate = `# This file was auto-generated by the Vanadium SysInit tool.
# Date: {{.Date}}
#
# {{.Service}} - {{.Description}}
#
# Upstart config for Ubuntu-GCE

description	"{{.Description}}"

start on runlevel [2345]
stop on runlevel [!2345]
{{if .Environment}}
# Environment variables
{{range $var, $value := .Environment}}
env {{$var}}={{$value}}{{end}}
{{end}}
respawn
respawn limit 10 5
umask 022

pre-start script
    test -x {{.Binary}} || { stop; exit 0; }
    mkdir -p -m0755 /var/log/veyron
    chown -R {{.User}} /var/log/veyron
end script

script
  set -e
  echo '{{.Service}} starting'
  exec sudo -u {{.User}} {{range $cmd := .Command}} {{$cmd}}{{end}}
end script
`

// Implements the InstallSystemInit method.
func (u *UpstartService) Install() error {
	file := fmt.Sprintf("%s/%s.conf", upstartDir, u.Service)
	return (*ServiceDescription)(u).writeTemplate(upstartTemplate, file)
}

// Print implements the InstallSystemInit method.
func (u *UpstartService) Print() error {
	return (*ServiceDescription)(u).writeTemplate(upstartTemplate, "")
}

// Implements the InstallSystemInit method.
func (u *UpstartService) Uninstall() error {
	// For now, ignore any errors returned by Stop, since Stop complains
	// when there is no instance to stop.
	// TODO(caprita): Only call Stop if there are running instances.
	u.Stop()
	file := fmt.Sprintf("%s/%s.conf", upstartDir, u.Service)
	return os.Remove(file)
}

// Start implements the InstallSystemInit method.
func (u *UpstartService) Start() error {
	return action(upstartBin, "start", u.Service)
}

// Stop implements the InstallSystemInit method.
func (u *UpstartService) Stop() error {
	return action(upstartBin, "stop", u.Service)
}

///////////////////////////////////////////////////////////////////////////////
// Systemd support

// SystemdService is the implementation of InstallSystemInit interfacing with
// the Systemd system.
type SystemdService ServiceDescription

const systemdTemplate = `# This file was auto-generated by the Vanadium SysInit tool.
# Date: {{.Date}}
#
# {{.Service}} - {{.Description}}
#
[Unit]
Description={{.Description}}
After=openntpd.service

[Service]
User={{.User}}{{if .Environment}}{{println}}Environment={{range $var, $value := .Environment}}"{{$var}}={{$value}}" {{end}}{{end}}
ExecStart={{range $cmd := .Command}}{{$cmd}} {{end}}
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=always
RestartSecs=10
StandardOutput=syslog


[Install]
WantedBy=multi-user.target
`

// Install implements the InstallSystemInit method.
func (s *SystemdService) Install() error {
	file := fmt.Sprintf("%s/%s.service", systemdDir, s.Service)
	if err := (*ServiceDescription)(s).writeTemplate(systemdTemplate, file); err != nil {
		return fmt.Errorf("failed to write template (uid= %d, euid= %d): %v", os.Getuid(), os.Geteuid(), err)
	}
	file = fmt.Sprintf("%s/veyron.conf", systemdTmpFileDir)
	f, err := os.Create(file)
	if err != nil {
		return err
	}
	f.WriteString("d /var/log/veyron 0755 veyron veyron\n")
	f.Close()
	err = action("systemd-tmpfiles", "--create", file)
	if err != nil {
		return err
	}

	// First call disable to get rid of any symlink lingering around from a previous install
	// We don't care about the return status on the disable action.
	action(findSystemdSystemCtl(), "disable", s.Service)
	return action(findSystemdSystemCtl(), "enable", s.Service)
}

// Print implements the InstallSystemInit method.
func (s *SystemdService) Print() error {
	return (*ServiceDescription)(s).writeTemplate(systemdTemplate, "")
}

// Uninstall implements the InstallSystemInit method.
func (s *SystemdService) Uninstall() error {
	if err := s.Stop(); err != nil {
		return err
	}
	if err := action(findSystemdSystemCtl(), "disable", s.Service); err != nil {
		return err
	}
	file := fmt.Sprintf("%s/%s.service", systemdDir, s.Service)
	return os.Remove(file)
}

// Start implements the InstallSystemInit method.
func (s *SystemdService) Start() error {
	return action(findSystemdSystemCtl(), "start", s.Service)
}

// Stop implements the InstallSystemInit method.
func (s *SystemdService) Stop() error {
	return action(findSystemdSystemCtl(), "stop", s.Service)
}

// This is a variable so it can be overridden for testing.
var findSystemdSystemCtl = func() string {
	// Systems using systemd may have systemctl in one of several possible places. This finds it.
	paths := []string{"/sbin", "/bin", "/usr/bin", "/usr/sbin"}

	for _, path := range paths {
		testpath := filepath.Join(path, "systemctl")
		if fi, err := os.Stat(testpath); err == nil && (fi.Mode()&0100) != 0 {
			return testpath
		}
	}

	return ""
}

///////////////////////////////////////////////////////////////////////////////
// Docker support

// DockerService is the implementation of InstallSystemInit interfacing with
// Docker.
type DockerService ServiceDescription

const dockerTemplate = `#!/bin/bash
# This file was auto-generated by the Vanadium SysInit tool.
# Date: {{.Date}}
#
# {{.Service}} - {{.Description}}
#
set -e
{{if .Environment}}
# Environment variables
{{range $var, $value := .Environment}}export {{$var}}={{$value}}{{end}}
{{end}}
echo '{{.Service}} setup.'
test -x {{.Binary}} || { stop; exit 0; }
mkdir -p -m0755 /var/log/veyron
chown -R {{.User}} /var/log/veyron

echo '{{.Service}} starting'
exec daemon -n {{.Service}} -r -A 2 -L 10 -M 5 -X '{{range $cmd := .Command}} {{$cmd}}{{end}}' &
`

// Install implements the InstallSystemInit method.
func (s *DockerService) Install() error {
	file := fmt.Sprintf("%s/%s.sh", dockerDir, s.Service)
	if err := (*ServiceDescription)(s).writeTemplate(dockerTemplate, file); err != nil {
		return err
	}
	os.Chmod(file, 0755)
	return nil
}

// Print implements the InstallSystemInit method.
func (s *DockerService) Print() error {
	return (*ServiceDescription)(s).writeTemplate(dockerTemplate, "")
}

// Uninstall implements the InstallSystemInit method.
func (s *DockerService) Uninstall() error {
	if err := s.Stop(); err != nil {
		return err
	}
	file := fmt.Sprintf("%s/%s.sh", dockerDir, s.Service)
	return os.Remove(file)
}

// Start implements the InstallSystemInit method.
func (s *DockerService) Start() error {
	return action(fmt.Sprintf("%s/%s.sh", dockerDir, s.Service), "", s.Service)
}

// Stop implements the InstallSystemInit method.
func (s *DockerService) Stop() error {
	return action("daemon", fmt.Sprintf("-n %s --stop", s.Service), s.Service)
}
