import re


def parse_file(filepath, settings):  # noqa: C901 (Skip complexity check)
    """Parse file for lines to skip, header, and available license

    Args:
        filepath (PosixPath): Path to the file
        settings (Dict): Settings Dictionary

    Returns:
        Dict: a dictionary with the following entries
            - skip: number of lines at the beginning to skip (always keep them when replacing or adding something)
                can also be seen as the index of the first line not to skip
            - headStart: index of first line of detected header, or None if no header detected
            - headEnd: index of last line of detected header, or None
            - haveLicense: found a line that matches a pattern that indicates this could be a license header
    """
    skip = 0
    head_start = None
    head_end = None
    have_license = False
    isBlockHeader = False

    with filepath.open('r') as f:
        lines = f.readlines()

    emptyPattern = re.compile(r'^\s*$')
    licensePattern = re.compile(r"license", re.IGNORECASE)

    keep_first = settings["keepFirst"]
    block_comment_start_pattern = settings["blockCommentStartPattern"]
    block_comment_end_pattern = settings["blockCommentEndPattern"]
    line_comment_start_pattern = settings["lineCommentStartPattern"]
    i = 0
    for line in lines:
        if (i == 0) and keep_first and keep_first.findall(line):
            skip = i + 1
        elif emptyPattern.findall(line):
            pass
        elif block_comment_start_pattern and block_comment_start_pattern.findall(line):
            head_start = i
            isBlockHeader = True
            break
        elif line_comment_start_pattern and line_comment_start_pattern.findall(line):
            head_start = i
            break
        elif not block_comment_start_pattern and \
                line_comment_start_pattern and \
                line_comment_start_pattern.findall(line):
            head_start = i
            break
        else:
            # we have reached something else, so no header in this file
            return {
                "skip": skip,
                "lines": lines,
                "headStart": None,
                "headEnd": None,
                "haveLicense": have_license
            }
        i = i + 1

    # now we have either reached the end, or we are at a line where a block start or line comment occurred
    # if we have reached the end, return default dictionary without info
    if i == len(lines):
        return {
            "skip": skip,
            "lines": lines,
            "headStart": head_start,
            "headEnd": head_end,
            "haveLicense": have_license
        }

    # otherwise process the comment block until it ends
    if isBlockHeader:
        for j in range(i, len(lines)):
            if licensePattern.findall(lines[j]):
                have_license = True
            elif block_comment_end_pattern.findall(lines[j]):
                return {
                    "skip": skip,
                    "lines": lines,
                    "headStart": head_start,
                    "headEnd": j,
                    "haveLicense": have_license
                }
        # if we went through all the lines without finding an end, maybe we have some syntax error or some other
        # unusual situation, so lets return no header
        return {
            "skip": skip,
            "lines": lines,
            "headStart": None,
            "headEnd": None,
            "haveLicense": have_license
        }
    else:
        # Just comment lines
        for j in range(i, len(lines)):
            if line_comment_start_pattern.findall(lines[j]) and licensePattern.findall(lines[j]):
                have_license = True
            elif not line_comment_start_pattern.findall(lines[j]):
                return {
                    "skip": skip,
                    "lines": lines,
                    "headStart": i,
                    "headEnd": j - 1,
                    "haveLicense": have_license
                }
        # if we went through all the lines without finding the end of the block, it could be that the whole
        # file only consisted of the header, so lets return the last line index
        return {
            "skip": skip,
            "lines": lines,
            "headStart": i,
            "headEnd": len(lines) - 1,
            "haveLicense": have_license
        }