package ledger

import (
	"bufio"
	"fmt"
	"io"
	"strings"
	"testing"
)

func TestTransactionPayee(t *testing.T) {
	given := Transaction{
		Delta{Name: "x", Transaction: "a", Value: 9},
		Delta{Name: "Withdrawal:z", Transaction: "a", Value: -3},
		Delta{Name: "Withdrawal:z", Transaction: "a", Value: -6},
	}

	got := given.Payee()
	if got != "x" {
		t.Error(got)
	}
}

func TestDeltasTransactions(t *testing.T) {
	given := Deltas{
		Delta{Date: "2", Name: "x", Transaction: "a"},
		Delta{Date: "2", Name: "y", Transaction: "a"},
		Delta{Date: "1", Name: "z", Transaction: "b"},
	}

	got := given.Transactions()
	if len(got) != 2 {
		t.Error(len(got))
	}
	if len(got[0]) != 1 {
		t.Error("first xaction is not earliest date", len(got[0]))
	}
	if len(got[1]) != 2 {
		t.Error("second xaction is not latest date", len(got[1]))
	}
}

func TestReadTransaction(t *testing.T) {
	cases := map[string]struct {
		input string
		want  transaction
		err   error
	}{
		"empty": {
			input: "",
			want:  transaction{},
			err:   io.EOF,
		},
		"white space": {
			input: "   ",
			want:  transaction{},
			err:   io.EOF,
		},
		"verbose": {
			input: `
2003-04-05=2003-04-06=2003-04-07 Reasoning here
   A:B   $1.00
   C:D   $-1.00
         `,
			want: transaction{
				date:        "2003-04-05",
				otherDates:  []string{"2003-04-06", "2003-04-07"},
				description: "Reasoning here",
				payee:       "A:B",
				recipients: []transactionRecipient{
					{
						name:     "C:D",
						value:    -1.0,
						currency: "$",
					},
				},
			},
			err: io.EOF,
		},
		"multi send": {
			input: `
2003-04-05            Reasoning here
   A:B   $1.00
   A:B   $2.00
   C:D
         `,
			want: transaction{
				date:        "2003-04-05",
				description: "Reasoning here",
				payee:       "C:D",
				recipients: []transactionRecipient{
					{
						name:     "A:B",
						value:    1.0,
						currency: "$",
					},
					{
						name:     "A:B",
						value:    2.0,
						currency: "$",
					},
				},
			},
			err: io.EOF,
		},
	}

	for name, d := range cases {
		c := d
		t.Run(name, func(t *testing.T) {
			r := bufio.NewReader(strings.NewReader(c.input))
			got, err := readTransaction("", r)
			if err != c.err {
				t.Error(err)
			}

			if fmt.Sprintf("%+v", got) != fmt.Sprintf("%+v", c.want) {
				t.Errorf("want\n\t%+v, got\n\t%+v", c.want, got)
			}
		})
	}
}
