package main

import (
	"errors"
	"fmt"
	"testing"
)

type parseArgsScenario struct {
	length  int
	lines   int
	pattern string
	help    bool
	err     error
	args    []string
}

func TestParseArgs(t *testing.T) {

	cases := []parseArgsScenario{
		{
			length:  30,
			lines:   10,
			pattern: "a-zA-Z0-9",
			args:    []string{},
		},
		{
			length:  10,
			lines:   1,
			pattern: "a-zA-Z0-9",
			args:    []string{"-s10"},
		},
		{
			length:  11,
			lines:   1,
			pattern: "a-zA-Z0-9",
			args:    []string{"-s", "11"},
		},
		{
			length:  12,
			lines:   1,
			pattern: "a-zA-Z0-9",
			args:    []string{"-s=12"},
		},
		{
			length:  3,
			lines:   4,
			pattern: "a-zA-Z0-9",
			args:    []string{"-s3x4"},
		},
		{
			length:  5,
			lines:   6,
			pattern: "a-zA-Z0-9",
			args:    []string{"-s", "5x6"},
		},
		{
			length:  7,
			lines:   8,
			pattern: "a-zA-Z0-9",
			args:    []string{"-s=7x8"},
		},
		{
			length:  1,
			lines:   1,
			pattern: "a-zA-Z0-9",
			help:    true,
			args:    []string{"-s-1"},
			err:     errors.New("invalid argument specified for option -s"),
		},
		{
			length:  1,
			lines:   1,
			pattern: "a-zA-Z0-9",
			help:    true,
			args:    []string{"-s5x-1"},
			err:     errors.New("invalid argument specified for option -s"),
		},
		{
			length:  1,
			lines:   1,
			pattern: "a-zA-Z0-9",
			help:    true,
			args:    []string{"-s", "-1"},
			err:     errors.New("invalid argument specified for option -s"),
		},
		{
			length:  1,
			lines:   1,
			pattern: "a-zA-Z0-9",
			help:    true,
			args:    []string{"-s", "-5x1"},
			err:     errors.New("invalid argument specified for option -s"),
		},
		{
			length:  1,
			lines:   1,
			pattern: "a-zA-Z0-9",
			help:    true,
			args:    []string{"-s0"},
			err:     errors.New("invalid argument specified for option -s"),
		},
		{
			length:  1,
			lines:   1,
			pattern: "a-zA-Z0-9",
			help:    true,
			args:    []string{"-s", "0"},
			err:     errors.New("invalid argument specified for option -s"),
		},
		{
			length:  1,
			lines:   1,
			pattern: "a-zA-Z0-9",
			help:    true,
			args:    []string{"-s", "5", "abc", "-h", "-s", "3"},
			err:     errors.New("unexpected argument -s"),
		},
		{
			length:  1,
			lines:   1,
			pattern: "a-zA-Z0-9",
			help:    true,
			args:    []string{"-s", "5", "abc", "--help", "-s3"},
			err:     errors.New("unexpected argument -s3"),
		},
		{
			length:  30,
			lines:   10,
			pattern: "abc def",
			args:    []string{"abc def"},
		},
		{
			length:  30,
			lines:   10,
			pattern: "abc def",
			help:    true,
			args:    []string{"abc def", "arg"},
			err:     errors.New("unexpected argument arg"),
		},
		{
			length:  1,
			lines:   1,
			pattern: "abc def",
			args:    []string{"abc def", "-s1"},
		},
		{
			length:  1,
			lines:   1,
			pattern: "abc def",
			args:    []string{"-s1", "abc def"},
		},
	}

	for _, c := range cases {

		length, lines, pattern, help, err := ParseArgs(c.args)
		failed := false

		if fmt.Sprintf("%v", err) != fmt.Sprintf("%v", c.err) {
			failed = true
			t.Errorf("error is [%v], should be [%v]", err, c.err)
		}

		if err == nil && length != c.length {
			failed = true
			t.Errorf("length is %v, should be %v", length, c.length)
		}

		if err == nil && lines != c.lines {
			failed = true
			t.Errorf("lines is %v, should be %v", lines, c.lines)
		}

		if err == nil && pattern != c.pattern {
			failed = true
			t.Errorf("pattern is %v, should be %v", pattern, c.pattern)
		}

		if help != c.help {
			failed = true
			t.Errorf("help is %v, should be %v", help, c.help)
		}

		if failed {
			t.Errorf("%v", c)
		}

	}

}