package lagrange_test

import (
	"math/big"
	"testing"

	"github.com/stretchr/testify/assert"

	"github.com/bandprotocol/chain/v3/pkg/tss/internal/lagrange"
)

func TestComputeCoefficient(t *testing.T) {
	tests := []struct {
		name string
		i    int64   // test description
		s    []int64 // hex encoded signature to parse
		exp  string
	}{{
		name: "1 from 1,2",
		i:    1,
		s:    []int64{1, 2},
		exp:  "2",
	}, {
		name: "2 from 1,2",
		i:    2,
		s:    []int64{1, 2},
		exp:  "115792089237316195423570985008687907852837564279074904382605163141518161494336",
	}, {
		name: "1 from 1,2,3",
		i:    1,
		s:    []int64{1, 2, 3},
		exp:  "3",
	}, {
		name: "2 from 1,2,4",
		i:    2,
		s:    []int64{1, 2, 4},
		exp:  "115792089237316195423570985008687907852837564279074904382605163141518161494335",
	}, {
		name: "3 from 1,3,4",
		i:    3,
		s:    []int64{1, 3, 4},
		exp:  "115792089237316195423570985008687907852837564279074904382605163141518161494335",
	}, {
		name: "4 from 2,3,4",
		i:    4,
		s:    []int64{2, 3, 4},
		exp:  "3",
	}, {
		name: "3 from 1,2,3,4,5",
		i:    3,
		s:    []int64{1, 2, 3, 4, 5},
		exp:  "10",
	}, {
		name: "18 from 3,5,8,10,13,14,16,18,19,20",
		i:    18,
		s:    []int64{3, 5, 8, 10, 13, 14, 16, 18, 19, 20},
		exp:  "115792089237316195423570985008687907852837564279074904382605163141518161493273",
	}, {
		name: "7 from 1,4,5,7,8,9,10,11,12,13,15,16,17,18,19",
		i:    7,
		s:    []int64{1, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19},
		exp:  "77194726158210796949047323339125271901891709519383269588403442094345440982228",
	}, {
		name: "9 from 1,4,5,7,8,9,10,11,12,13,15,16,17,18,19",
		i:    9,
		s:    []int64{1, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19},
		exp:  "57896044618658097711785492504343953926418782139537452191302581570759080631696",
	}, {
		name: "10 from 1,4,5,7,8,9,10,11,12,13,15,16,17,18,19",
		i:    10,
		s:    []int64{1, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19},
		exp:  "90060513851245929773888543895646150552206994439280481186470682443403014659823",
	}, {
		name: "12 from 1,4,5,7,8,9,10,11,12,13,15,16,17,18,19",
		i:    12,
		s:    []int64{1, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19},
		exp:  "66166908135609254527754848576393090201621465302328516790060093223724663819024",
	}, {
		name: "6 from 2,4,5,6,7,8,9,10,12,13,14,15,17,18,19,20",
		i:    6,
		s:    []int64{2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18, 19, 20},
		exp:  "31579660701086235115519359547823974868955699348838610286165044493141316716126",
	}, {
		name: "13 from 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20",
		i:    13,
		s:    []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
		exp:  "77520",
	}}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			res := lagrange.ComputeCoefficient(test.i, test.s)
			exp, _ := new(big.Int).SetString(test.exp, 10)

			assert.Equal(t, exp, res)

			res = lagrange.ComputeCoefficientPreCompute(test.i, test.s)
			assert.Equal(t, exp, res)
		})
	}
}
