// 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"
	"os/exec"
	"time"
)

// Formatter formats generated source code
type Formatter interface {
	// Format formats source code.
	Format(source []byte) ([]byte, error)
}

// identifyFormatter returns the input unmodified
type identityFormatter struct{}

func (f identityFormatter) Format(source []byte) ([]byte, error) {
	return source, nil
}

// externalFormatter formats a writer stream.
type externalFormatter struct {
	path  string
	args  []string
	limit int
}

var _ = []Formatter{identityFormatter{}, externalFormatter{}}

const timeout = 2 * time.Minute

// NewFormatter creates a new external 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 {
	if path == "" {
		return identityFormatter{}
	}
	return externalFormatter{
		path: path,
		args: args,
	}
}

// NewFormatterWithSizeLimit creates a new external formatter that doesn't
// attempt to format sources over a specified size.
//
// If the source is within the size limit, but the formatted output exceeds it,
// then it discards the output and returns the unformatted source. This ensures
// that running it multiple times (which happens when we reformat golden files)
// will either invoke the external formatter every time or not at all.
//
// 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 NewFormatterWithSizeLimit(limit int, path string, args ...string) Formatter {
	if path == "" {
		return identityFormatter{}
	}
	return externalFormatter{
		path:  path,
		args:  args,
		limit: limit,
	}
}

func (f externalFormatter) Format(source []byte) ([]byte, error) {
	if f.limit > 0 && len(source) > f.limit {
		return source, nil
	}
	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()
	cmd := exec.CommandContext(ctx, f.path, f.args...)
	formattedBuf := new(bytes.Buffer)
	cmd.Stdout = formattedBuf
	errBuf := new(bytes.Buffer)
	cmd.Stderr = errBuf
	in, err := cmd.StdinPipe()
	if err != nil {
		return nil, fmt.Errorf("Error creating stdin pipe: %w", err)
	}
	if err := cmd.Start(); err != nil {
		return nil, fmt.Errorf("Error starting formatter process: %w", err)
	}
	if _, err := in.Write(source); err != nil {
		return nil, fmt.Errorf("Error writing stdin: %w", err)
	}
	if err := in.Close(); err != nil {
		return nil, fmt.Errorf("Error closing stdin: %w", err)
	}
	if err := cmd.Wait(); err != nil {
		if errContent := errBuf.Bytes(); len(errContent) != 0 {
			return nil, fmt.Errorf("Formatter (%v) error: %w (stderr: %s)", cmd, err, string(errContent))
		}
		return nil, fmt.Errorf("Formatter (%v) error but stderr was empty: %w", cmd, err)
	}
	if f.limit > 0 && formattedBuf.Len() > f.limit {
		return source, nil
	}
	return formattedBuf.Bytes(), nil
}
