#!/usr/bin/env python3

import os
import sys


SINGLE_COMMENT_MARKERS = ('#',)
BAT_COMMENT_MARKERS = ('rem',)
MULTI_COMMENT_MARKERS = ('/*', ' *', ' */')  # Start, during, end
XML_COMMENT_MARKERS = ('<!--', '  ~', '  -->')  # Start, during, end

if not len(sys.argv) == 2:
    print('Usage: replace-license <file_with_new_license>')
    print('\nReplace the license header in all files under current directory with the new license.\n')
    sys.exit(1)

new_license_file = sys.argv[1]

SINGLE_LICENSE = ('{0}\n{0}' + '{0}'.join(open(new_license_file).readlines())
                  + '{0}\n').format(SINGLE_COMMENT_MARKERS[0])
BAT_LICENSE = ('{0}\n{0}' + '{0}'.join(open(new_license_file).readlines())
               + '{0}\n').format(BAT_COMMENT_MARKERS[0])
MULTI_LICENSE = ((MULTI_COMMENT_MARKERS[0] + '\n{0}'
                  + '{0}'.join(open(new_license_file).readlines())).format(MULTI_COMMENT_MARKERS[1])
                 + MULTI_COMMENT_MARKERS[2] + '\n')
XML_LICENSE = ((XML_COMMENT_MARKERS[0] + '\n{0}'
                + '{0}'.join(open(new_license_file).readlines())).format(XML_COMMENT_MARKERS[1])
               + XML_COMMENT_MARKERS[2] + '\n')

replace_count = 0


def replace_license(source_file):
    before_comment = []
    first_comment = []
    after_comment = []

    first_comment_finished = False
    is_single = False
    is_bat = False
    is_xml = False

    with open(source_file) as fp:
        for line in fp:
            if first_comment_finished:
                after_comment.append(line)

            elif (line.startswith(SINGLE_COMMENT_MARKERS + MULTI_COMMENT_MARKERS
                                  + BAT_COMMENT_MARKERS + XML_COMMENT_MARKERS)
                  and not (line.startswith('#!') or 'suppress inspection' in line)):
                if line.startswith(SINGLE_COMMENT_MARKERS[0]):
                    is_single = True
                if line.startswith(BAT_COMMENT_MARKERS[0]):
                    is_bat = True
                if line.startswith(XML_COMMENT_MARKERS[0]):
                    is_xml = True

                if line.startswith((MULTI_COMMENT_MARKERS[2], XML_COMMENT_MARKERS[2])):
                    first_comment_finished = True
                else:
                    first_comment.append(line)

            elif first_comment:
                after_comment.append(line)
                first_comment_finished = True

            else:
                before_comment.append(line)

    if first_comment and 'License' in '\n'.join(first_comment):
        with open(source_file, 'w') as fp:
            for line in before_comment:
                fp.write(line)

            if is_single:
                fp.write(SINGLE_LICENSE)
            elif is_bat:
                fp.write(BAT_LICENSE)
            elif is_xml:
                fp.write(XML_LICENSE)
            else:
                fp.write(MULTI_LICENSE)

            for line in after_comment:
                fp.write(line)

        return True

    return False


for root, dirs, files in os.walk('.'):
    if '/.' in root:
        continue

    if root.endswith('/licenses'):
        continue

    for name in files:
        if name.startswith('.'):
            continue

        source_file = os.path.join(root, name)

        try:
            if replace_license(source_file):
                replace_count += 1

        except UnicodeDecodeError:  # Binary file
            pass

        except Exception:
            print('Failed to update', source_file)
            raise

print('Replaced {} file(s)'.format(replace_count))
