#!/usr/bin/python3

"""Perform various database-related operations."""

import os
import sys
import dbm


def usage(retval: int) -> None:
    """Output a usage message."""
    if retval == 0:
        file_ = sys.stdout
    else:
        file_ = sys.stderr
    file_.write('Usage: {}\n'.format(sys.argv[0]))
    file_.write('       --dump-keys filename                         dump keys of filename\n')
    file_.write('       --dump-keys-and-values filename              dump keys and values of filename\n')
    file_.write('       --dump-value filename key                    dump value of filename at key\n')
    file_.write('       --write-key-value-pair filename key value    write value in filename at key\n')
    file_.write('       --erase-key-value-pair filename key          erase key and its value\n')
    sys.exit(retval)


PERMS = 6*64 + 4*8 + 4


def dump_keys(filename: str) -> None:
    """Dump the keys in the database."""
    database = dbm.open(filename, 'c', PERMS)
    for key in database.keys():
        os.write(1, key + b'\n')


def dump_keys_and_values(filename: str) -> None:
    """Dump the keys and the values of a database."""
    database = dbm.open(filename, 'c', PERMS)
    for key in database.keys():
        os.write(1, key + b' ' + database[key] + b'\n')


def dump_value(filename: str, key: str) -> None:
    """Dump the value at key."""
    database = dbm.open(filename, 'c', PERMS)
    if key in database:
        os.write(1, database[key] + b'\n')
    else:
        sys.stderr.write('No such key: {}\n'.format(key))
        sys.exit(1)


def write_key_value(filename: str, key: str, value: str) -> None:
    """Write a key-value pair to the database."""
    database = dbm.open(filename, 'c', PERMS)
    if key in database:
        del database[key]
    database[key] = value


def erase_key_value(filename: str, key: str) -> None:
    """Erase a key-value pair from the database."""
    database = dbm.open(filename, 'c', PERMS)
    if key in database:
        del database[key]
    else:
        sys.stderr.write('no such key: '+sys.argv[3]+'\n')


def main() -> None:
    """Parse command line and perform database operations."""
    if len(sys.argv) == 3 and sys.argv[1] == '--dump-keys':
        dump_keys(sys.argv[2])
    elif len(sys.argv) == 3 and sys.argv[1] == '--dump-keys-and-values':
        dump_keys_and_values(sys.argv[2])
    elif len(sys.argv) == 4 and sys.argv[1] == '--dump-value':
        dump_value(sys.argv[2], sys.argv[3])
    elif len(sys.argv) == 5 and sys.argv[1] == '--write-key-value-pair':
        write_key_value(sys.argv[2], sys.argv[3], sys.argv[4])
    elif len(sys.argv) == 4 and sys.argv[1] == '--erase-key-value-pair':
        erase_key_value(sys.argv[2], sys.argv[3])
    elif sys.argv[1] in ['-h', '--help']:
        usage(0)
    else:
        sys.stderr.write('{}: Unrecognized option: {}\n'.format(sys.argv[0], sys.argv[1]))
        usage(1)
    sys.exit(0)


main()