from __future__ import print_function

import argparse

from pre_commit_hooks.util import entry


class Requirement(object):

    def __init__(self):
        super(Requirement, self).__init__()
        self.value = None
        self.comments = []

    def __lt__(self, requirement):
        # \n means top of file comment, so always return True,
        # otherwise just do a string comparison with value.
        if self.value == b'\n':
            return True
        elif requirement.value == b'\n':
            return False
        else:
            return self.value < requirement.value


def fix_requirements(f):
    requirements = []
    before = []
    after = []

    for line in f:
        before.append(line)

        # If the most recent requirement object has a value, then it's time to
        # start building the next requirement object.
        if not len(requirements) or requirements[-1].value is not None:
            requirements.append(Requirement())

        requirement = requirements[-1]

        # If we see a newline before any requirements, then this is a top of
        # file comment.
        if len(requirements) == 1 and line.strip() == b'':
            if len(requirement.comments) and requirement.comments[0].startswith(b'#'):
                requirement.value = b'\n'
            else:
                requirement.comments.append(line)
        elif line.startswith(b'#') or line.strip() == b'':
            requirement.comments.append(line)
        else:
            requirement.value = line

    for requirement in sorted(requirements):
        for comment in requirement.comments:
            after.append(comment)
        after.append(requirement.value)

    before_string = b''.join(before)
    after_string = b''.join(after)

    if before_string == after_string:
        return 0
    else:
        f.seek(0)
        f.write(after_string)
        f.truncate()
        return 1


@entry
def fix_requirements_txt(argv):
    parser = argparse.ArgumentParser()
    parser.add_argument('filenames', nargs='*', help='Filenames to fix')
    args = parser.parse_args(argv)

    retv = 0

    for arg in args.filenames:
        with open(arg, 'rb+') as f:
            retv |= fix_requirements(f)

    return retv
