// Copyright 2019 The Fuchsia 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 fidlgen

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"os/exec"
	"time"
)

// Formatter formats a writer stream.
type Formatter struct {
	path string
	args []string
}

const timeout = 2 * time.Minute

// NewFormatter creates a new formatter.
//
// The `path` needs to either
// * Point to an executable which formats stdin and outputs it to stdout;
// * An empty string, in which case no formatting will occur.
func NewFormatter(path string, args ...string) Formatter {
	return Formatter{
		path: path,
		args: args,
	}
}

// FormatPipe formats an output stream.
//
// If there is a error during formatting, the unformatted input will be written and an error will
// be returned.
//
// When the returned WriteCloser is closed, 'out' will also be closed.
// This allows the caller to close the writer in a single location and received all relevant errors.
func (f Formatter) FormatPipe(out io.WriteCloser) (io.WriteCloser, error) {
	if f.path == "" {
		return unformattedStream{normalOut: out}, nil
	}
	return formattedStream{
		path:           f.path,
		args:           f.args,
		out:            out,
		unformattedBuf: new(bytes.Buffer),
	}, nil
}

var _ = []io.WriteCloser{
	unformattedStream{},
	formattedStream{},
}

type unformattedStream struct {
	normalOut io.Writer
}

func (s unformattedStream) Write(p []byte) (int, error) {
	return s.normalOut.Write(p)
}

func (s unformattedStream) Close() error {
	// Not the responsibility of unformattedStream to close underlying stream
	// which may (or may not) be an io.WriteCloser.
	return nil
}

type formattedStream struct {
	path           string
	args           []string
	out            io.WriteCloser
	unformattedBuf *bytes.Buffer
}

func (s formattedStream) Write(p []byte) (int, error) {
	return s.unformattedBuf.Write(p)
}

func (s formattedStream) Close() error {
	defer s.out.Close()
	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()
	cmd := exec.CommandContext(ctx, s.path, s.args...)
	formattedBuf := new(bytes.Buffer)
	cmd.Stdout = formattedBuf
	errBuf := new(bytes.Buffer)
	cmd.Stderr = errBuf
	in, err := cmd.StdinPipe()
	if err != nil {
		s.out.Write(s.unformattedBuf.Bytes())
		return err
	}
	if err := cmd.Start(); err != nil {
		s.out.Write(s.unformattedBuf.Bytes())
		return err
	}
	if _, err := in.Write(s.unformattedBuf.Bytes()); err != nil {
		s.out.Write(s.unformattedBuf.Bytes())
		return err
	}
	if err := in.Close(); err != nil {
		s.out.Write(s.unformattedBuf.Bytes())
		return err
	}
	if err := cmd.Wait(); err != nil {
		s.out.Write(s.unformattedBuf.Bytes())
		if errContent := errBuf.Bytes(); len(errContent) != 0 {
			return fmt.Errorf("%s: %s", err, string(errContent))
		}
		return err
	}
	_, err = s.out.Write(formattedBuf.Bytes())
	return err
}
