#!python

import enum
import os
import system_calls
import sys


class errors(enum.IntEnum):
    NOT_SUPPORTED_SYSTEM_CALL = -1
    NO_SUCH_SYSTEM_CALL = -2


def help():
    print("""usage: syscall [-h] syscall arch

Check for Linux system call number/name and availability.

positional arguments:
  syscall     system call number/name
  arch        requested architecture (optional)

options:
  -h, --help  show this help message and exit

Examples:
  syscall openat arm64
  syscall 56
  syscall 123 mipso32
""")
    sys.exit()


def search_for_syscall_by_number(syscall_number):
    for syscall_name in syscalls.names():
        try:
            if syscall_number == syscalls.get(syscall_name, syscall_arch):
                return syscall_name
        except system_calls.NotSupportedSystemCall:
            pass


def search_for_syscall_by_name(syscall_name):
    try:
        syscall_number = syscalls.get(syscall_name, syscall_arch)
    except system_calls.NotSupportedSystemCall:
        syscall_number = errors.NOT_SUPPORTED_SYSTEM_CALL
    except system_calls.NoSuchSystemCall:
        syscall_number = errors.NO_SUCH_SYSTEM_CALL

    return syscall_number


if len(sys.argv) == 1 or sys.argv[1] in ["-h", "--help"]:
    help()

syscall_arch = os.uname().machine

syscalls = system_calls.syscalls()

if len(sys.argv) == 3:
    if sys.argv[2] in syscalls.archs():
        syscall_arch = sys.argv[2]
    else:
        print(f"Architecture {sys.argv[2]} is not supported.")
        sys.exit()

if sys.argv[1].isnumeric():
    syscall_number = int(sys.argv[1])
    syscall_name = search_for_syscall_by_number(syscall_number)
else:
    syscall_name = sys.argv[1]
    syscall_number = search_for_syscall_by_name(syscall_name)

if syscall_number >= 0 and syscall_name is not None:
    print(f"On {syscall_arch} system call number {syscall_number} "
          f"is {syscall_name}()")
elif syscall_name is None:
    print(f"On {syscall_arch} there is no system call with {syscall_number} "
          f"number.")
elif syscall_number == errors.NOT_SUPPORTED_SYSTEM_CALL:
    print(f"On {syscall_arch} system call {syscall_name}() is not supported.")
elif syscall_number == errors.NO_SUCH_SYSTEM_CALL:
    print(f"There is no such system call as {syscall_name}().")
