from io import StringIO
import csv

__author__ = 'Darryl Oatridge'


class DelimitedParser(object):

    @staticmethod
    def read_dsv(file_stream: StringIO, fieldnames=None, restkey=None, restval=None, dialect=None, delimiter=None,
                 quotechar=None, escapechar=None, doublequote=None, skipinitialspace=None, lineterminator=None,
                 quoting=None) -> dict:
        """ reads an StringIO stream and returns a dictionary of the delimited file. (see python csv documentation)

        :param file_stream: a String IO file stream to parse
        :param fieldnames: a set of field names for the dictionary if no header
        :param restkey: If row has more fields than fieldnames, remaining data is put in a list under restkey
        :param restval: If non-blank row has fewer fields than fieldnames, values are filled-in with restval
        :param dialect: Dialect class grouping formatting parameters
        :param delimiter: A one-character string used to separate fields. It defaults to ','.
        :param quotechar: A one-character string used to quote fields containing special characters, such as the
                    delimiter or quotechar, or which contain new-line characters. It defaults to '"'.
        :param escapechar: A one-character string used by the writer to escape the delimiter if quoting is set to
                    QUOTE_NONE and the quotechar if doublequote is False.
        :param doublequote: Controls how instances of quotechar appearing inside a field should themselves be quoted.
                    When True, the character is doubled. Default
                    When False, the escapechar is used as a prefix to the quotechar
        :param skipinitialspace: When True, whitespace immediately following the delimiter is ignored. Default False
        :param lineterminator: The string used to terminate lines produced by the writer.
        :param quoting: Controls when quotes should be generated by the writer and recognised by the reader
        :return: dict
        """
        # params
        fieldnames = fieldnames if isinstance(fieldnames, str) else None
        restkey = restkey if isinstance(restkey, str) else None
        restval = restval if isinstance(restval, str) else None
        dialect = dialect if isinstance(dialect, str) else csv.unix_dialect
        # dialect
        if isinstance(delimiter, str):
            dialect.delimiter = delimiter
        if isinstance(escapechar, str):
            dialect.escapechar = escapechar
        if isinstance(doublequote, str):
            dialect.doublequote = doublequote
        if isinstance(skipinitialspace, str):
            dialect.skipinitialspace = skipinitialspace
        if isinstance(lineterminator, str):
            dialect.lineterminator = lineterminator
        if isinstance(quotechar, str):
            dialect.quotechar = quotechar
        if isinstance(quoting, str):
            dialect.quoting = quoting
        reader = csv.DictReader(file_stream, fieldnames=fieldnames, restkey=restkey, restval=restval, dialect=dialect)
        rtn_dict = {}
        for line in reader:
            for k, v in line.items():
                if k not in rtn_dict:
                    rtn_dict[k] = []
                rtn_dict.get(k).append(v)
        return rtn_dict
