package model

import "strings"

// ChainNetwork identifies a blockchain network for routing and discovery.
type ChainNetwork string

const (
	ChainNetworkArbitrumOne     ChainNetwork = "arbitrum_one"
	ChainNetworkArbitrumSepolia ChainNetwork = "arbitrum_sepolia"
	ChainNetworkEthereumMainnet ChainNetwork = "ethereum_mainnet"
	ChainNetworkTronMainnet     ChainNetwork = "tron_mainnet"
	ChainNetworkTronNile        ChainNetwork = "tron_nile"
	ChainNetworkUnspecified     ChainNetwork = ""
)

// AllChainNetworks returns all valid chain networks.
func AllChainNetworks() []ChainNetwork {
	return []ChainNetwork{
		ChainNetworkArbitrumOne,
		ChainNetworkEthereumMainnet,
		ChainNetworkTronMainnet,
		ChainNetworkTronNile,
	}
}

// ParseChainNetwork parses a string into a ChainNetwork.
// Returns the network and true if valid, or empty and false if invalid.
func ParseChainNetwork(value string) (ChainNetwork, bool) {
	v := strings.ToLower(strings.TrimSpace(value))
	switch v {
	case "arbitrum_one", "arbitrum", "arb":
		return ChainNetworkArbitrumOne, true
	case "ethereum_mainnet", "ethereum", "eth":
		return ChainNetworkEthereumMainnet, true
	case "tron_mainnet", "tron":
		return ChainNetworkTronMainnet, true
	case "tron_nile", "nile":
		return ChainNetworkTronNile, true
	case "unspecified", "":
		return ChainNetworkUnspecified, true
	default:
		return ChainNetworkUnspecified, false
	}
}

// String returns the string representation of the network.
func (n ChainNetwork) String() string {
	return string(n)
}

// IsValid returns true if the network is a known valid network.
func (n ChainNetwork) IsValid() bool {
	switch n {
	case ChainNetworkArbitrumOne,
		ChainNetworkEthereumMainnet,
		ChainNetworkTronMainnet,
		ChainNetworkTronNile:
		return true
	default:
		return false
	}
}

// IsTron returns true if the network is a TRON network.
func (n ChainNetwork) IsTron() bool {
	switch n {
	case ChainNetworkTronMainnet, ChainNetworkTronNile:
		return true
	default:
		return false
	}
}

// IsEVM returns true if the network is an EVM-compatible network.
func (n ChainNetwork) IsEVM() bool {
	switch n {
	case ChainNetworkArbitrumOne, ChainNetworkEthereumMainnet:
		return true
	default:
		return false
	}
}

// IsTestnet returns true if the network is a testnet.
func (n ChainNetwork) IsTestnet() bool {
	switch n {
	case ChainNetworkTronNile:
	case ChainNetworkArbitrumSepolia:
		return true
	default:
	}
	return false
}
