package main

import (
	"fmt"
	"os"

	"github.com/BurntSushi/toml"
	"github.com/urfave/cli"
)

type runConfig struct {
	Image   string `toml:"image"`
	Process struct {
		Args []string `toml:"args"`
		Env  []string `toml:"env"`
		Cwd  string   `toml:"cwd"`
		Uid  int      `toml:"uid"`
		Gid  int      `toml:"gid"`
		Tty  bool     `toml:"tty"`
	} `toml:"process"`
	Network struct {
		Type    string `toml:"type"`
		IP      string `toml:"ip"`
		Gateway string `toml:"gateway"`
	} `toml:"network"`
}

var runCommand = cli.Command{
	Name:  "run",
	Usage: "run a container",
	Action: func(context *cli.Context) error {
		var config runConfig
		if _, err := toml.DecodeFile(context.Args().First(), &config); err != nil {
			return err
		}
		id := context.Args().Get(1)
		if id == "" {
			return fmt.Errorf("containerd must be provided")
		}
		client, err := getClient(context)
		if err != nil {
			return err
		}
		clone, err := client.Images.Clone(config.Image)
		if err != nil {
			return err
		}
		container, err := client.Containers.Create(CreateRequest{
			Id:     id,
			Mounts: clone.Mounts,
			Process: Process{
				Args:   config.Args,
				Env:    config.Env,
				Cwd:    config.Cwd,
				Uid:    config.Uid,
				Gid:    config.Gid,
				Tty:    config.Tty,
				Stdin:  os.Stdin.Name(),
				Stdout: os.Stdout.Name(),
				Stderr: os.Stderr.Name(),
			},
			Owner: "ctr",
		})
		defer client.Containers.Delete(container)
		if err := client.Networks.Attach(config.Network, container); err != nil {
			return err
		}
		if err := client.Containers.Start(container); err != nil {
			return err
		}
		go forwarSignals(client.Containers.SignalProcess, container.Process)
		events, err := client.Containers.Events(container.Id)
		if err != nil {
			return err
		}
		for event := range events {
			if event.Type == "exit" {
				os.Exit(event.Status)
			}
		}
		return nil
	},
}