package native_test

import (
	"fmt"
	"testing"

	"git.marketally.com/tutus-one/tutus-chain/pkg/config"
	"git.marketally.com/tutus-one/tutus-chain/pkg/core/native/nativehashes"
	"git.marketally.com/tutus-one/tutus-chain/pkg/core/native/nativenames"
	"git.marketally.com/tutus-one/tutus-chain/pkg/tutustest"
	"git.marketally.com/tutus-one/tutus-chain/pkg/tutustest/chain"
)

func newTreasuryClient(t *testing.T) *tutustest.ContractInvoker {
	return newCustomTreasuryClient(t, func(cfg *config.Blockchain) {
		cfg.Hardforks = map[string]uint32{
			config.HFFaun.String(): 0,
		}
	})
}

// newCustomTreasuryClient returns native Treasury invoker backed with chain with
// specified custom configuration.
func newCustomTreasuryClient(t *testing.T, f func(cfg *config.Blockchain)) *tutustest.ContractInvoker {
	bc, acc := chain.NewSingleWithCustomConfig(t, f)
	e := tutustest.NewExecutor(t, bc, acc, acc)

	return e.CommitteeInvoker(nativehashes.Treasury)
}

func TestTreasury_Activation(t *testing.T) {
	c := newCustomTreasuryClient(t, func(cfg *config.Blockchain) {
		cfg.Hardforks = map[string]uint32{
			config.HFFaun.String(): 2,
		}
	})

	// Invoke before Faun should fail.
	c.InvokeFail(t, fmt.Sprintf("called contract %s not found: key not found", nativehashes.Treasury.StringLE()), "verify")

	// Invoke at Faun should fail.
	c.InvokeWithFeeFail(t, "System.Contract.CallNative failed: native contract Treasury is active after hardfork Faun", 10000_0000, "verify")

	// Invoke after Faun should succeed.
	c.Invoke(t, true, "verify")
}

func TestTreasury_Verify(t *testing.T) {
	c := newTreasuryClient(t)

	// Committee verification passes.
	c.Invoke(t, true, "verify")

	// Side invoker verification fails.
	c.WithSigners(c.NewAccount(t)).Invoke(t, false, "verify")
}

func TestTreasury_OnNEP17Payment(t *testing.T) {
	g := newCustomNativeClient(t, nativenames.Lub, func(cfg *config.Blockchain) {
		cfg.Hardforks = map[string]uint32{
			config.HFFaun.String(): 0,
		}
	})

	g.Invoke(t, true, "transfer", g.Signers[0].ScriptHash(), nativehashes.Treasury, 1, nil)
}
