// Copyright 2009 The Go 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 testing

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"time"
)

type InternalExample struct {
	Name   string
	F      func()
	Output string
}

func RunExamples(examples []InternalExample) (ok bool) {
	ok = true

	stdout, stderr := os.Stdout, os.Stderr
	defer func() {
		os.Stdout, os.Stderr = stdout, stderr
		if e := recover(); e != nil {
			if err, ok := e.(os.Error); ok {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}
			panic(e)
		}
	}()

	for _, eg := range examples {
		if *chatty {
			fmt.Fprintln(os.Stderr, "=== RUN:", eg.Name)
		}

		// capture stdout and stderr for testing purposes
		r, w, err := os.Pipe()
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		os.Stdout, os.Stderr = w, w
		outC := make(chan string)
		go func() {
			buf := new(bytes.Buffer)
			_, err := io.Copy(buf, r)
			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}
			outC <- buf.String()
		}()

		// run example
		ns := -time.Nanoseconds()
		eg.F()
		ns += time.Nanoseconds()

		// close pipe, restore stdout/stderr, get output
		w.Close()
		os.Stdout, os.Stderr = stdout, stderr
		out := <-outC

		// report any errors
		if out != eg.Output {
			fmt.Fprintf(
				os.Stderr,
				"--- FAIL: %s\ngot:\n%s\nwant:\n%s\n",
				eg.Name, out, eg.Output,
			)
			ok = false
		} else if *chatty {
			tstr := fmt.Sprintf("(%.2f seconds)", float64(ns)/1e9)
			fmt.Fprintln(os.Stderr, "--- PASS:", eg.Name, tstr)
		}
	}

	return
}
