package solver

import (
	"log"
	"strings"
	"testing"

	"github.com/fhltang/sudokugen/internal/solver"
	"github.com/fhltang/sudokugen/internal/sudoku"
)

var (
	valid10 = []string{
		`832597164
761843295
94.1..873
4.3769528
2.73.8946
698452317
12468573.
.7.931482
38.274651
`,
		`194867235
328195746
57.3..198
8.7419562
4.95.2371
215673984
98274165.
.5.938427
74.256819
`,
		`452791683
396824715
71.3..942
5.9287461
6.75.3829
821649357
16493527.
.8.472136
27.168594
`,
		`485169327
273584196
96.7..845
3.8615974
6.48.7231
197243658
71295648.
.4.371562
53.428719
`,
		`943625817
651987432
27.4..965
4.7368591
3.51.2678
186759324
76453128.
.1.896743
83.274156
`,
	}
	valid40 = []string{
		`.6451..7.
..5789.6.
9..6...85
..28.139.
3....76..
5.79.6.2.
..61..2..
.9.3..548
23.4..716
`,
		`.7568..2.
..2745.3.
3..1...45
..49.867.
8....64..
6.75.4.81
..62..3..
.4.8..567
15.4..29.
`,
		`.4269..1.
..5847.2.
6..5...73
..62.854.
8....46..
5.49.6.8.
..34..1..
.5.7..238
96.3.275.
`,
		`.1679..2.
..5628.1.
8..4...63
..95.614.
5....92..
6.12.4.7.
..28..3..
.5.9..784
78.3.569.
`,
		`.2359..1.
..1426.8.
7..8...92
..71.964.
1....49.5
4.92.5.7.
..49..2..
.8.7..169
91.3..75.
`,
	}
	valid50 = []string{
		`....8..1.
.41657.3.
3..9...57
...5.142.
9.....5..
..28.6.9.
..9......
.3.4..162
...2..9.8
`,
		`....2..13
..945178.
1..7...5.
..53.619.
9.....5.7
...9.5.2.
..7......
.1.6..9.4
3..5..8..
`,
		`....2..3.
..1968.2.
8..1...5.
...4.679.
7....56..
4..3.2.8.
..9...8..
.5.2..3.9
.7.6..2.4
`,
		`.2..3..5.
..3219.4.
6..7...3.
...1.536.
4....25..
5..8.7.2.
..4......
.8.9..4.6
71.5..2..
`,
		`....9..5.
..5481.7.
7..5...6.
..72.814.
1....39..
2..9.5.3.
..4......
.2.8..513
...1..48.
`,
	}
)

func benchmarkSolve(b *testing.B, boards []string) {
	for i := 0; i < b.N; i++ {
		s := solver.New()
		for _, data := range boards {
			board, err := sudoku.Parse(strings.NewReader(data))
			if err != nil {
				log.Fatal(err)
			}
			s.Reset()
			s.Solve(board, 2)
		}
	}
}

func BenchmarkSolveValid10(b *testing.B) {
	benchmarkSolve(b, valid10)
}

func BenchmarkSolveValid40(b *testing.B) {
	benchmarkSolve(b, valid40)
}

func BenchmarkSolveValid50(b *testing.B) {
	benchmarkSolve(b, valid40)
}
