import pytest

import vyper
from vyper import opcodes
from vyper.exceptions import CompilerPanic


@pytest.fixture(params=list(opcodes.EVM_VERSIONS))
def evm_version(request):
    default = opcodes.active_evm_version
    opcodes.active_evm_version = opcodes.EVM_VERSIONS[request.param]
    yield request.param
    opcodes.active_evm_version = default


def test_opcodes():
    code = """
@external
def a() -> bool:
    return True
    """

    out = vyper.compile_code(code, ["opcodes_runtime", "opcodes"])

    assert len(out["opcodes"]) > len(out["opcodes_runtime"])
    assert out["opcodes_runtime"] in out["opcodes"]


def test_version_check_no_begin_or_end():
    with pytest.raises(CompilerPanic):
        opcodes.version_check()


def test_version_check(evm_version):
    assert opcodes.version_check(begin=evm_version)
    assert opcodes.version_check(end=evm_version)
    assert opcodes.version_check(begin=evm_version, end=evm_version)
    if evm_version not in ("byzantium", "atlantis"):
        assert not opcodes.version_check(end="byzantium")
    if evm_version != "istanbul":
        assert not opcodes.version_check(begin="istanbul")


def test_get_opcodes(evm_version):
    op = opcodes.get_opcodes()
    if evm_version == "istanbul":
        assert "CHAINID" in op
        assert op["SLOAD"][-1] == 800
    else:
        assert "CHAINID" not in op
        assert op["SLOAD"][-1] == 200
    if evm_version in ("byzantium", "atlantis"):
        assert "CREATE2" not in op
    else:
        assert op["CREATE2"][-1] == 32000
