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

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"sync"
	"syscall"
	"time"

	"v.io/x/lib/cmdline"
)

// Sequence provides for convenient chaining of multiple calls to its
// methods to avoid repeated tests for error returns. The usage is:
//
// err := s.Run("echo", "a").Run("echo", "b").Done()
//
// The first method to encounter an error short circuits any following
// methods and the result of that first error is returned by the
// Done method or any of the other 'terminating methods' (see below).
// Sequence is not thread safe. It also good practice to use a new
// instance of a Sequence in defer's.
//
// Unless directed to specific stdout and stderr io.Writers using Capture(),
// the stdout and stderr output from the command is discarded, unless an error
// is encountered, in which case the output from the command that failed (both
// stdout and stderr) is written to the stderr io.Writer specified via
// NewSequence. In addition, in verbose mode, command execution logging
// is written to the stdout an stderr io.Writers configured via NewSequence.
//
// Modifier methods are provided that influence the behaviour of the
// next invocation of the Run method to set timeouts (Timed), to
// capture output (Capture), input (Read) and to set the environment (Env).
// For example, the following will result in a timeout error.
//
// err := s.Timeout(time.Second).Run("sleep","10").Done()
// err := s.Timeout(time.Second).Last("sleep","10")
//
// A sequence of commands must be terminated with a call to a 'terminating'
// method. The simplest are the Done or Last methods used in the examples above,
// but there are other methods which typically return results in addition to
// error, such as ReadFile(filename string) ([]byte, error). Here the usage
// would be:
//
// o.Stdout, _ = os.Create("foo")
// data, err := s.Capture(o, nil).Run("echo","b").ReadFile("foo")
// // data == "b"
//
// Note that terminating functions, even those that take an action, may
// return an error generated by a previous method.
//
// In addition to Run which will always run a command as a subprocess,
// the Call method will invoke a function. Note that Capture and Timeout
// do not affect such calls.
//
// Errors returned by Sequence augment those returned by the underlying
// packages with details of the exact call that generated those errors.
// This means that it is not possible to test directly for errors from
// those packages. The GetOriginalError function can be used to obtain
// the error from the underlying package, or the IsTimeout, IsNotExists etc
// functions can be used on the wrapped error. The ExitCode method
// is also provided to convert to the exit codes expected by the
// v.io/x/lib/cmdline package which is often used in conjunction with
// Sequence.
type Sequence struct {
	// NOTE: we use a struct as the return value of all
	// Sequence methods to ensure that code of the form:
	// if err := s.WriteFile(); err != nil {...}
	// does not compile.
	*sequence
}

type sequence struct {
	r                            *Run
	err                          error
	caller                       string
	stdout, stderr               io.Writer
	stdin                        io.Reader
	reading                      bool
	env                          map[string]string
	opts                         *Opts
	defaultStdin                 io.Reader
	defaultStdout, defaultStderr io.Writer
	dirs                         []string
	verbosity                    *bool
	timeout                      time.Duration
	serializedWriterLock         sync.Mutex
}

// NewSequence creates an instance of Sequence with default values for its
// environment, stdin, stderr, stdout and other supported options.
func NewSequence(env map[string]string, stdin io.Reader, stdout, stderr io.Writer, color, dryRun, verbose bool) Sequence {
	s := Sequence{
		&sequence{
			r:            NewRun(env, stdin, stdout, stderr, color, dryRun, verbose),
			defaultStdin: stdin,
		},
	}
	s.defaultStdout, s.defaultStderr = s.serializeWriter(stdout), s.serializeWriter(stderr)
	return s
}

// Capture arranges for the next call to Run or Last to write its stdout and
// stderr output to the supplied io.Writers. This will be cleared and not used
// for any calls to Run or Last beyond the next one. Specifying nil for
// a writer will result in using the the corresponding io.Writer supplied
// to NewSequence. ioutil.Discard should be used to discard output.
func (s Sequence) Capture(stdout, stderr io.Writer) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	s.stdout, s.stderr = stdout, stderr
	return Sequence{s.sequence}
}

// Read arranges for the next call to Run or Last to read from the supplied
// io.Reader. This will be cleared and not used for any calls to Run or Last
// beyond the next one. Specifying nil will result in reading from os.DevNull.
func (s Sequence) Read(stdin io.Reader) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	s.reading = true
	s.stdin = stdin
	return Sequence{s.sequence}
}

// Env arranges for the next call to Run, Call or Last to use the supplied
// environment variables. This will be cleared and not used for any calls
// to Run, Call or Last beyond the next one.
func (s Sequence) Env(env map[string]string) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	s.env = env
	return Sequence{s.sequence}
}

// Verbosity arranges for the next call to Run, Call or Last to use the specified
// verbosity. This will be cleared and not used for any calls
// to Run, Call or Last beyond the next one.
func (s Sequence) Verbose(verbosity bool) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	s.verbosity = &verbosity
	return Sequence{s.sequence}
}

// internal getOpts that doesn't override stdin, stdout, stderr
func (s Sequence) getOpts() Opts {
	var opts Opts
	if s.opts != nil {
		opts = *s.opts
	} else {
		opts = s.r.Opts()
	}
	return opts
}

// Timeout arranges for the next call to Run or Last to be subject to the
// specified timeout. The timeout will be cleared and not used any calls to Run
// or Last beyond the next one. It has no effect for calls to Call.
func (s Sequence) Timeout(timeout time.Duration) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	s.timeout = timeout
	return Sequence{s.sequence}
}

func (s Sequence) setOpts(opts Opts) {
	s.opts = &opts
}

type wrappedError struct {
	oe, we error
}

func (ie *wrappedError) Error() string {
	return ie.we.Error()
}

// Error returns the error, if any, stored in the Sequence.
func (s Sequence) Error() error {
	if s.err != nil && len(s.caller) > 0 {
		return &wrappedError{oe: s.err, we: fmt.Errorf("%s: %v", s.caller, s.err)}
	}
	return Sequence{s.sequence}.err
}

// TranslateExitCode translates errors from the "os/exec" package that
// contain exit codes into cmdline.ErrExitCode errors.
func TranslateExitCode(err error) error {
	return translateExitCode(GetOriginalError(err))
}

func translateExitCode(err error) error {
	if exit, ok := err.(*exec.ExitError); ok {
		if wait, ok := exit.Sys().(syscall.WaitStatus); ok {
			if status := wait.ExitStatus(); wait.Exited() && status != 0 {
				return cmdline.ErrExitCode(status)
			}
		}
	}
	return err
}

// GetOriginalError gets the original error wrapped in the supplied err.
// If the given err has not been wrapped by Sequence, then the supplied error
// is returned.
func GetOriginalError(err error) error {
	if we, ok := err.(*wrappedError); ok {
		return we.oe
	}
	return err
}

// IsExist returns a boolean indicating whether the error is known
// to report that a file or directory already exists.
func IsExist(err error) bool {
	if we, ok := err.(*wrappedError); ok {
		return os.IsExist(we.oe)
	}
	return os.IsExist(err)
}

// IsNotExist returns a boolean indicating whether the error is known
// to report that a file or directory does not exist.
func IsNotExist(err error) bool {
	if we, ok := err.(*wrappedError); ok {
		return os.IsNotExist(we.oe)
	}
	return os.IsNotExist(err)
}

// IsPermission returns a boolean indicating whether the error is known
// to report that permission is denied.
func IsPermission(err error) bool {
	if we, ok := err.(*wrappedError); ok {
		return os.IsPermission(we.oe)
	}
	return os.IsPermission(err)
}

// IsTimeout returns a boolean indicating whether the error is a result of
// a timeout.
func IsTimeout(err error) bool {
	if we, ok := err.(*wrappedError); ok {
		return we.oe == commandTimedOutErr
	}
	return err == commandTimedOutErr
}

func fmtError(depth int, err error, detail string) string {
	_, file, line, _ := runtime.Caller(depth + 1)
	return fmt.Sprintf("%s:%d: %s", filepath.Base(file), line, detail)
}

func (s Sequence) setError(err error, detail string) {
	if err == nil || s.err != nil {
		return
	}
	s.err = err
	s.caller = fmtError(2, err, detail)
}

func (s Sequence) reset() {
	s.stdin, s.stdout, s.stderr, s.env = nil, nil, nil, nil
	s.opts, s.verbosity = nil, nil
	s.reading = false
	s.timeout = 0
}

func (s Sequence) done(p1, p2 *io.PipeWriter, stdinCh, stderrCh chan error) error {
	p1.Close()
	p2.Close()
	defer s.reset()
	if stdinCh != nil {
		if err := <-stdinCh; err != nil {
			return err
		}
	}
	if stderrCh != nil {
		if err := <-stderrCh; err != nil {
			return err
		}
	}
	return nil
}

func useIfNotNil(a, b io.Writer) io.Writer {
	if a != nil {
		return a
	}
	return b
}

func writeOutput(logdir bool, from string, to io.Writer) {
	if fi, err := os.Open(from); err == nil {
		io.Copy(to, fi)
		fi.Close()
	}
	if !logdir {
		return
	}
	if wd, err := os.Getwd(); err == nil {
		fmt.Fprintf(to, "Current Directory: %v\n", wd)
	}
}

type sharedLockWriter struct {
	mu *sync.Mutex
	f  io.Writer
}

func (lw *sharedLockWriter) Write(d []byte) (int, error) {
	lw.mu.Lock()
	defer lw.mu.Unlock()
	return lw.f.Write(d)
}

func (s Sequence) serializeWriter(a io.Writer) io.Writer {
	if a != nil {
		return &sharedLockWriter{&s.serializedWriterLock, a}
	}
	return nil
}

func (s Sequence) initAndDefer() func() {
	if s.stdout == nil && s.stderr == nil {
		fout, err := ioutil.TempFile("", "seq")
		if err != nil {
			return func() {}
		}
		opts := s.getOpts()
		opts.Stdout, opts.Stderr = s.serializeWriter(fout), s.serializeWriter(fout)
		opts.Env = s.env
		if s.reading {
			opts.Stdin = s.stdin
		}
		if s.verbosity != nil {
			opts.Verbose = *s.verbosity
		}
		s.setOpts(opts)
		return func() {
			filename := fout.Name()
			fout.Close()
			defer func() { os.Remove(filename); s.opts = nil }()
			if s.err != nil {
				writeOutput(true, filename, useIfNotNil(s.defaultStderr, os.Stderr))
			}
			if opts.Verbose && s.defaultStderr != s.defaultStdout {
				writeOutput(false, filename, useIfNotNil(s.defaultStdout, os.Stdout))
			}
		}
	}
	opts := s.getOpts()
	rStdout, wStdout := io.Pipe()
	rStderr, wStderr := io.Pipe()
	opts.Stdout = wStdout
	opts.Stderr = wStderr
	opts.Env = s.env
	if s.reading {
		opts.Stdin = s.stdin
	}
	var stdinCh, stderrCh chan error
	stdout, stderr := s.serializeWriter(s.stdout), s.serializeWriter(s.stderr)
	if stdout != nil {
		stdinCh = make(chan error)
		go copy(stdout, rStdout, stdinCh)
	} else {
		opts.Stdout = s.defaultStdout
	}
	if stderr != nil {
		stderrCh = make(chan error)
		go copy(stderr, rStderr, stderrCh)
	} else {
		opts.Stderr = s.defaultStderr
	}
	if s.verbosity != nil {
		opts.Verbose = *s.verbosity
	}
	s.setOpts(opts)
	return func() {
		if err := s.done(wStdout, wStderr, stdinCh, stderrCh); err != nil && s.err == nil {
			s.err = err
		}
	}
}

func fmtArgs(args ...interface{}) string {
	if len(args) == 0 {
		return ""
	}
	var out bytes.Buffer
	for _, a := range args {
		switch at := a.(type) {
		case string:
			fmt.Fprintf(&out, ", %q", at)
		default:
			fmt.Fprintf(&out, ", %v", a)
		}
	}
	return out.String()
}

func fmtStringArgs(args ...string) string {
	if len(args) == 0 {
		return ""
	}
	var out bytes.Buffer
	for _, a := range args {
		fmt.Fprintf(&out, ", %q", a)
	}
	return out.String()
}

// Pushd pushes the current directory onto a stack and changes directory
// to the specified one. Calling any terminating function will pop back
// to the first element in the stack on completion of that function.
func (s Sequence) Pushd(dir string) Sequence {
	cwd, err := os.Getwd()
	if err != nil {
		s.setError(err, "Pushd("+dir+"): os.Getwd")
		return Sequence{s.sequence}
	}
	s.dirs = append(s.dirs, cwd)
	s.setError(s.r.Chdir(dir), "Pushd("+dir+")")
	return Sequence{s.sequence}
}

// Popd popds the last directory from the directory stack and chdir's to it.
// Calling any termination function will pop back to the first element in
// the stack on completion of that function.
func (s Sequence) Popd() Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	if len(s.dirs) == 0 {
		s.setError(fmt.Errorf("directory stack is empty"), "Popd()")
		return Sequence{s.sequence}
	}
	last := s.dirs[len(s.dirs)-1]
	s.dirs = s.dirs[:len(s.dirs)-1]
	s.setError(s.r.Chdir(last), "Popd() -> "+last)
	return Sequence{s.sequence}
}

// Run runs the given command as a subprocess.
func (s Sequence) Run(path string, args ...string) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	defer s.initAndDefer()()
	s.setError(s.r.command(s.timeout, s.getOpts(), path, args...), fmt.Sprintf("Run(%q%s)", path, fmtStringArgs(args...)))
	return Sequence{s.sequence}
}

// Last runs the given command as a subprocess and returns an error
// immediately terminating the sequence, it is equivalent to
// calling s.Run(path, args...).Done().
func (s Sequence) Last(path string, args ...string) error {
	if s.err != nil {
		return s.Done()
	}
	defer s.Done()
	defer s.initAndDefer()()
	s.setError(s.r.command(s.timeout, s.getOpts(), path, args...), fmt.Sprintf("Last(%q%s)", path, fmtStringArgs(args...)))
	return Sequence{s.sequence}.err
}

// Call runs the given function. Note that Capture and Timeout have no
// effect on invocations of Call, but Opts can control logging.
func (s Sequence) Call(fn func() error, format string, args ...interface{}) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	defer s.initAndDefer()()
	s.setError(s.r.FunctionWithOpts(s.getOpts(), fn, format, args...), fmt.Sprintf("Call(%s%s)", format, fmtArgs(args)))
	return Sequence{s.sequence}
}

// Chdir is a wrapper around os.Chdir that handles options such as
// "verbose" or "dry run".
func (s Sequence) Chdir(dir string) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	s.setError(s.r.Chdir(dir), "Chdir("+dir+")")
	return Sequence{s.sequence}
}

// Chmod is a wrapper around os.Chmod that handles options such as
// "verbose" or "dry run".
func (s Sequence) Chmod(dir string, mode os.FileMode) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	if err := s.r.Chmod(dir, mode); err != nil {
		s.setError(err, fmt.Sprintf("Chmod(%s, %s)", dir, mode))
	}
	return Sequence{s.sequence}
}

// MkdirAll is a wrapper around os.MkdirAll that handles options such
// as "verbose" or "dry run".
func (s Sequence) MkdirAll(dir string, mode os.FileMode) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	s.setError(s.r.MkdirAll(dir, mode), fmt.Sprintf("MkdirAll(%s, %s)", dir, mode))
	return Sequence{s.sequence}
}

// RemoveAll is a wrapper around os.RemoveAll that handles options
// such as "verbose" or "dry run".
func (s Sequence) RemoveAll(dir string) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	s.setError(s.r.RemoveAll(dir), fmt.Sprintf("RemoveAll(%s)", dir))
	return Sequence{s.sequence}
}

// Remove is a wrapper around os.Remove that handles options
// such as "verbose" or "dry run".
func (s Sequence) Remove(file string) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	s.setError(s.r.Remove(file), fmt.Sprintf("Remove(%s)", file))
	return Sequence{s.sequence}
}

// Rename is a wrapper around os.Rename that handles options such as
// "verbose" or "dry run".
func (s Sequence) Rename(src, dst string) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	s.setError(s.r.Rename(src, dst), fmt.Sprintf("Rename(%s, %s)", src, dst))
	return Sequence{s.sequence}
}

// Symlink is a wrapper around os.Symlink that handles options such as
// "verbose" or "dry run".
func (s Sequence) Symlink(src, dst string) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	s.setError(s.r.Symlink(src, dst), fmt.Sprintf("Symlink(%s, %s)", src, dst))
	return Sequence{s.sequence}
}

// Output logs the given list of lines using the currently in effect verbosity
// as specified by Opts, or the default otherwise.
func (s Sequence) Output(output []string) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	opts := s.getOpts()
	if s.verbosity != nil {
		opts.Verbose = *s.verbosity
	}
	s.r.OutputWithOpts(opts, output)
	return Sequence{s.sequence}
}

// Fprintf calls fmt.Fprintf.
func (s Sequence) Fprintf(f io.Writer, format string, args ...interface{}) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	fmt.Fprintf(f, format, args...)
	return Sequence{s.sequence}
}

// Done returns the error stored in the Sequence and pops back to the first
// entry in the directory stack if Pushd has been called. Done is a terminating
// function. There is no need to ensure that Done is called before returning
// from a function that uses a sequence unless it is necessary to pop the
// stack.
func (s Sequence) Done() error {
	rerr := s.Error()
	s.err = nil
	s.caller = ""
	s.reset()
	if len(s.dirs) > 0 {
		cwd := s.dirs[0]
		s.dirs = nil
		if err := s.r.Chdir(cwd); err != nil {
			detail := "Done: Chdir(" + cwd + ")"
			if rerr == nil {
				s.setError(err, detail)
			} else {
				// In the unlikely event that Chdir fails in addition to an
				// earlier error, we append an appropriate error message.
				s.err = fmt.Errorf("%v\n%v", rerr, fmtError(1, err, detail))
			}
			return s.Error()
		}
	}
	return rerr
}

// Open is a wrapper around os.Open that handles options such as
// "verbose" or "dry run". Open is a terminating function.
func (s Sequence) Open(name string) (*os.File, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	f, err := s.r.Open(name)
	s.setError(err, fmt.Sprintf("Open(%s)", name))
	return f, s.Done()
}

// OpenFile is a wrapper around os.OpenFile that handles options such as
// "verbose" or "dry run". OpenFile is a terminating function.
func (s Sequence) OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	f, err := s.r.OpenFile(name, flag, perm)
	s.setError(err, fmt.Sprintf("OpenFile(%s, %s, %s)", name, flag, perm))
	return f, s.Done()
}

// Create is a wrapper around os.Create that handles options such as "verbose"
// or "dry run". Create is a terminating function.
func (s Sequence) Create(name string) (*os.File, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	f, err := s.r.Create(name)
	s.setError(err, fmt.Sprintf("Create(%s)", name))
	return f, s.Done()
}

// ReadDir is a wrapper around ioutil.ReadDir that handles options
// such as "verbose" or "dry run". ReadDir is a terminating function.
func (s Sequence) ReadDir(dirname string) ([]os.FileInfo, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	fi, err := s.r.ReadDir(dirname)
	s.setError(err, fmt.Sprintf("ReadDir(%s)", dirname))
	return fi, s.Done()
}

// ReadFile is a wrapper around ioutil.ReadFile that handles options
// such as "verbose" or "dry run". ReadFile is a terminating function.
func (s Sequence) ReadFile(filename string) ([]byte, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	data, err := s.r.ReadFile(filename)
	s.setError(err, fmt.Sprintf("ReadFile(%s)", filename))
	return data, s.Done()
}

// WriteFile is a wrapper around ioutil.WriteFile that handles options
// such as "verbose" or "dry run".
func (s Sequence) WriteFile(filename string, data []byte, perm os.FileMode) Sequence {
	if s.err != nil {
		return Sequence{s.sequence}
	}
	err := s.r.WriteFile(filename, data, perm)
	s.setError(err, fmt.Sprintf("WriteFile(%s, %10s,  %s)", filename, data, perm))
	return Sequence{s.sequence}
}

// Copy is a wrapper around io.Copy that handles options such as "verbose" or
// "dry run". Copy is a terminating function.
func (s Sequence) Copy(dst *os.File, src io.Reader) (int64, error) {
	if s.err != nil {
		return 0, s.Done()
	}
	n, err := s.r.Copy(dst, src)
	s.setError(err, fmt.Sprintf("Copy(%s, %s)", dst, src))
	return n, s.Done()
}

// Stat is a wrapper around os.Stat that handles options such as
// "verbose" or "dry run". Stat is a terminating function.
func (s Sequence) Stat(name string) (os.FileInfo, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	fi, err := s.r.Stat(name)
	s.setError(err, fmt.Sprintf("Stat(%s)", name))
	return fi, s.Done()
}

// Lstat is a wrapper around os.Lstat that handles options such as
// "verbose" or "dry run". Lstat is a terminating function.
func (s Sequence) Lstat(name string) (os.FileInfo, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	fi, err := s.r.Lstat(name)
	s.setError(err, fmt.Sprintf("Lstat(%s)", name))
	return fi, s.Done()
}

// Readlink is a wrapper around os.Readlink that handles options such as
// "verbose" or "dry run". Lstat is a terminating function.
func (s Sequence) Readlink(name string) (string, error) {
	if s.err != nil {
		return "", s.Done()
	}
	link, err := s.r.Readlink(name)
	s.setError(err, fmt.Sprintf("Readlink(%s)", name))
	return link, s.Done()
}

// TempDir is a wrapper around ioutil.TempDir that handles options
// such as "verbose" or "dry run". TempDir is a terminating function.
func (s Sequence) TempDir(dir, prefix string) (string, error) {
	if s.err != nil {
		return "", s.Done()
	}
	name, err := s.r.TempDir(dir, prefix)
	s.setError(err, fmt.Sprintf("TempDir(%s,%s)", dir, prefix))
	return name, s.Done()
}

// IsDir is a wrapper around os.Stat with appropriate logging.
// IsDir is a terminating function.
func (s Sequence) IsDir(dirname string) (bool, error) {
	if s.err != nil {
		return false, s.Done()
	}
	t, err := s.r.IsDir(dirname)
	s.setError(err, fmt.Sprintf("IsDir(%s)", dirname))
	return t, s.Done()
}

// DirExists tests if a directory exists with appropriate logging.
// DirExists is a terminating function.
func (s Sequence) DirectoryExists(dir string) (bool, error) {
	if s.err != nil {
		return false, s.Done()
	}
	isdir, err := s.r.IsDir(dir)
	if err != nil {
		return false, s.Done()
	}
	return isdir, s.Done()
}

// FileExists tests if a file exists with appropriate logging.
// FileExists is a terminating function.
func (s Sequence) FileExists(file string) (bool, error) {
	if s.err != nil {
		return false, s.Done()
	}
	_, err := s.r.Stat(file)
	return err == nil, s.Done()
}

func copy(to io.Writer, from io.Reader, ch chan error) {
	_, err := io.Copy(to, from)
	ch <- err
}
