func CasketfileFromPipe(f *os.File, serverType string) (Input, error) {
	fi, err := f.Stat()
	if err == nil && fi.Mode()&os.ModeCharDevice == 0 {
		confBody, err := ioutil.ReadAll(f)
		if err != nil {
			return nil, err
		}
		return CasketfileInput{
			Contents:       confBody,
			Filepath:       f.Name(),
			ServerTypeName: serverType,
		}, nil
	}
	return nil, nil
}
CasketfileFromPipe loads the Casketfile input from f if f is
not interactive input. f is assumed to be a pipe or stream,
such as os.Stdin. If f is not a pipe, no error is returned
but the Input value will be nil. An error is only returned
if there was an error reading the pipe, even if the length
of what was read is 0.
package casket
import (
	"bytes"
	"encoding/gob"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"os"
	"strconv"
	"strings"
	"sync"
	"time"
	"github.com/tmpim/casket/casketfile"
	"github.com/tmpim/casket/telemetry"
)
var (
	AppName string
	AppVersion string
	Quiet bool
	PidFile string
	GracefulTimeout time.Duration
	isUpgrade = os.Getenv("CASKET__UPGRADE") == "1"
	started bool
	mu sync.Mutex
)
func init() {
	OnProcessExit = append(OnProcessExit, func() {
		if PidFile != "" {
			os.Remove(PidFile)
		}
	})
}
type Instance struct {
	serverType string
	casketfileInput Input
	wg *sync.WaitGroup
	context Context
	servers []ServerListener
	OnFirstStartup  []func() error  
	OnStartup       []func() error  
	OnRestart       []func() error  
	OnRestartFailed []func() error  
	OnShutdown      []func() error  
	OnFinalShutdown []func() error  
	Storage   map[interface{}]interface{}
	StorageMu sync.RWMutex
}
func Instances() []*Instance {
	return instances
}
func (i *Instance) Servers() []ServerListener { return i.servers }
func (i *Instance) Stop() error {
	for _, s := range i.servers {
		if gs, ok := s.server.(GracefulServer); ok {
			if err := gs.Stop(); err != nil {
				log.Printf("[ERROR] Stopping %s: %v", gs.Address(), err)
			}
		}
	}
	instancesMu.Lock()
	for j, other := range instances {
		if other == i {
			instances = append(instances[:j], instances[j+1:]...)
			break
		}
	}
	instancesMu.Unlock()
	return nil
}
func (i *Instance) ShutdownCallbacks() []error {
	var errs []error
	for _, shutdownFunc := range i.OnShutdown {
		err := shutdownFunc()
		if err != nil {
			errs = append(errs, err)
		}
	}
	for _, finalShutdownFunc := range i.OnFinalShutdown {
		err := finalShutdownFunc()
		if err != nil {
			errs = append(errs, err)
		}
	}
	return errs
}
func (i *Instance) Restart(newCasketfile Input) (*Instance, error) {
	log.Println("[INFO] Reloading")
	i.wg.Add(1)
	defer i.wg.Done()
	var err error
	defer func() {
		r := recover()
		if err != nil || r != nil {
			for _, fn := range i.OnRestartFailed {
				if err := fn(); err != nil {
					log.Printf("[ERROR] Restart failed callback returned error: %v", err)
				}
			}
			if err != nil {
				log.Printf("[ERROR] Restart failed: %v", err)
			}
			if r != nil {
				log.Printf("[PANIC] Restart: %v", r)
			}
		}
	}()
	for _, fn := range i.OnRestart {
		err = fn()
		if err != nil {
			return i, err
		}
	}
	if newCasketfile == nil {
		newCasketfile = i.casketfileInput
	}
	restartFds := make(map[string]restartTriple)
	for _, s := range i.servers {
		gs, srvOk := s.server.(GracefulServer)
		ln, lnOk := s.listener.(Listener)
		pc, pcOk := s.packet.(PacketConn)
		if srvOk {
			if lnOk && pcOk {
				restartFds[gs.Address()] = restartTriple{server: gs, listener: ln, packet: pc}
				continue
			}
			if lnOk {
				restartFds[gs.Address()] = restartTriple{server: gs, listener: ln}
				continue
			}
			if pcOk {
				restartFds[gs.Address()] = restartTriple{server: gs, packet: pc}
				continue
			}
		}
	}
	newInst := &Instance{serverType: newCasketfile.ServerType(), wg: i.wg, Storage: make(map[interface{}]interface{})}
	err = startWithListenerFds(newCasketfile, newInst, restartFds)
	if err != nil {
		return i, fmt.Errorf("starting with listener file descriptors: %v", err)
	}
	err = i.Stop()
	if err != nil {
		return i, err
	}
	for _, shutdownFunc := range i.OnShutdown {
		err = shutdownFunc()
		if err != nil {
			return i, err
		}
	}
	EmitEvent(InstanceStartupEvent, newInst)
	log.Println("[INFO] Reloading complete")
	return newInst, nil
}
func (i *Instance) SaveServer(s Server, ln net.Listener) {
	i.servers = append(i.servers, ServerListener{server: s, listener: ln})
}
type TCPServer interface {
	Listen() (net.Listener, error)
	Serve(net.Listener) error
}
type UDPServer interface {
	ListenPacket() (net.PacketConn, error)
	ServePacket(net.PacketConn) error
}
type Server interface {
	TCPServer
	UDPServer
}
type Stopper interface {
	Stop() error
}
type GracefulServer interface {
	Server
	Stopper
	Address() string
	WrapListener(net.Listener) net.Listener
}
type Listener interface {
	net.Listener
	File() (*os.File, error)
}
type PacketConn interface {
	net.PacketConn
	File() (*os.File, error)
}
type AfterStartup interface {
	OnStartupComplete()
}
func LoadCasketfile(serverType string) (Input, error) {
	if IsUpgrade() {
		err := gob.NewDecoder(os.Stdin).Decode(&loadedGob)
		if err != nil {
			return nil, err
		}
		return loadedGob.Casketfile, nil
	}
	cdyfile, err := loadCasketfileInput(serverType)
	if err != nil {
		return nil, err
	}
	if cdyfile == nil {
		cdyfile = DefaultInput(serverType)
	}
	if cdyfile == nil {
		cdyfile = CasketfileInput{ServerTypeName: serverType}
	}
	return cdyfile, nil
}
func (i *Instance) Wait() {
	i.wg.Wait()
}