/*
 * ECAL
 *
 * Copyright 2020 Matthias Ladkau. All rights reserved.
 *
 * This Source Code Form is subject to the terms of the MIT
 * License, If a copy of the MIT License was not distributed with this
 * file, You can obtain one at https://opensource.org/licenses/MIT.
 */

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"strings"
	"testing"
)

const InvalidFileName = "**" + string(0x0)

func TestGenerate(t *testing.T) {
	filename = InvalidFileName
	generateDoc = false

	var buf bytes.Buffer
	stderrPrint = func(v ...interface{}) (int, error) {
		buf.WriteString(fmt.Sprint(v...))
		return 0, nil
	}
	stdoutPrint = func(v ...interface{}) (int, error) {
		return 0, nil
	}

	main()

	if buf.String() != "Error:open **"+string(0)+": invalid argument" {
		t.Error("Unexpected output:", buf.String())
		return
	}

	filename = "test_out.txt"

	pkgNames = map[string][]string{
		"math": {"Pi"},
		"fmt":  {"Println"},
	}

	defer func() {
		os.Remove(filename)
	}()

	main()

	out, err := ioutil.ReadFile(filename)

	if err != nil {
		t.Error("Could not read file:", filename, " ", err)
		return
	}

	if string(out) != `
// Code generated by ecal/stdlib/generate; DO NOT EDIT.

package stdlib

import (
	"fmt"
	"math"
	"reflect"
)

/*
genStdlib contains all generated stdlib constructs.
*/
var genStdlib = map[interface{}]interface{}{
	"fmt-synopsis" : "Package fmt",
	"fmt-const" : fmtConstMap,
	"fmt-func" : fmtFuncMap,
	"fmt-func-doc" : fmtFuncDocMap,
	"math-synopsis" : "Package math",
	"math-const" : mathConstMap,
	"math-func" : mathFuncMap,
	"math-func-doc" : mathFuncDocMap,
}

/*
fmtConstMap contains the mapping of stdlib fmt constants.
*/
var fmtConstMap = map[interface{}]interface{}{
}

/*
fmtFuncDocMap contains the documentation of stdlib fmt functions.
*/
var fmtFuncDocMap = map[interface{}]interface{}{
	"Println": "Function: Println",
}

/*
fmtFuncMap contains the mapping of stdlib fmt functions.
*/
var fmtFuncMap = map[interface{}]interface{}{
	"Println": &ECALFunctionAdapter{reflect.ValueOf(fmt.Println), fmt.Sprint(fmtFuncDocMap["Println"])},
}

/*
mathConstMap contains the mapping of stdlib math constants.
*/
var mathConstMap = map[interface{}]interface{}{
	"Pi": float64(math.Pi),
}

/*
mathFuncDocMap contains the documentation of stdlib math functions.
*/
var mathFuncDocMap = map[interface{}]interface{}{
}

/*
mathFuncMap contains the mapping of stdlib math functions.
*/
var mathFuncMap = map[interface{}]interface{}{
}

// Dummy statement to prevent declared and not used errors
var Dummy = fmt.Sprint(reflect.ValueOf(fmt.Sprint))

` {
		t.Errorf("Unexpected result: Go string: %#v\nNormal output: %v", string(out), string(out))
		return
	}

	generateDoc = true

	main()

	out, err = ioutil.ReadFile(filename)

	if err != nil {
		t.Error("Could not read file:", filename, " ", err)
		return
	}

	if !strings.Contains(string(out), "formats using the default formats") {
		t.Error("Unexpected result:", string(out))
		return
	}
}
