import re


def _normalize(sresult, normalize_identifiers=False):
    """Normalize test output so it can be compared with the expected result.

    Several dynamic elements of a pycsw response (such as time,
    updateSequence, etc) are replaced with static constants to ease comparison.

    Parameters
    ----------
    sresult: str
        The test result as a unicode string.
    normalize_identifiers: bool, optional
        Whether identifier fields should be normalized.

    Returns
    -------
    str
        The normalized response.

    """

    # XML responses
    version = re.search(r'<!-- (.*) -->', sresult)
    updatesequence = re.search(r'updateSequence="(\S+)"', sresult)
    timestamp = re.search(r'timestamp="(.*)"', sresult)
    timestamp2 = re.search(r'timeStamp="(.*)"', sresult)
    timestamp3 = re.search(
        r'<oai:responseDate>(.*)</oai:responseDate>',
        sresult
    )
    timestamp4 = re.search(
        r'<oai:earliestDatestamp>(.*)</oai:earliestDatestamp>',
        sresult
    )
    zrhost = re.search(r'<zr:host>(.*)</zr:host>', sresult)
    zrport = re.search(r'<zr:port>(.*)</zr:port>', sresult)
    elapsed_time = re.search(r'elapsedTime="(.*)"', sresult)
    expires = re.search(r'expires="(.*?)"', sresult)
    atom_updated = re.findall(r'<atom:updated>(.*)</atom:updated>',
                              sresult)
    if version:
        sresult = sresult.replace(version.group(0),
                                  r'<!-- PYCSW_VERSION -->')
    if updatesequence:
        sresult = sresult.replace(updatesequence.group(0),
                                  r'updateSequence="PYCSW_UPDATESEQUENCE"')
    if timestamp:
        sresult = sresult.replace(timestamp.group(0),
                                  r'timestamp="PYCSW_TIMESTAMP"')
    if timestamp2:
        sresult = sresult.replace(timestamp2.group(0),
                                  r'timeStamp="PYCSW_TIMESTAMP"')
    if timestamp3:
        sresult = sresult.replace(
            timestamp3.group(0),
            r'<oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>'
        )
    if timestamp4:
        sresult = sresult.replace(
            timestamp4.group(0),
            r'<oai:earliestDatestamp>PYCSW_TIMESTAMP</oai:earliestDatestamp>'
        )
    if zrport:
        sresult = sresult.replace(zrport.group(0),
                                  r'<zr:port>PYCSW_PORT</zr:port>')
    if zrhost:
        sresult = sresult.replace(zrhost.group(0),
                                  r'<zr:host>PYCSW_HOST</zr:host>')
    if elapsed_time:
        sresult = sresult.replace(elapsed_time.group(0),
                                  r'elapsedTime="PYCSW_ELAPSED_TIME"')
    if expires:
        sresult = sresult.replace(expires.group(0),
                                  r'expires="PYCSW_EXPIRES"')
    for au in atom_updated:
        sresult = sresult.replace(au, r'PYCSW_TIMESTAMP')
    # for csw:HarvestResponse documents, mask identifiers
    # which are dynamically generated for OWS endpoints
    if sresult.find(r'HarvestResponse') != -1:
        identifier = re.findall(
            r'<dc:identifier>(\S+)</dc:identifier>',
            sresult
        )
        for i in identifier:
            sresult = sresult.replace(i, r'PYCSW_IDENTIFIER')
    # JSON responses
    timestamp = re.search(r'"@timestamp": "(.*?)"', sresult)

    if timestamp:
        sresult = sresult.replace(timestamp.group(0),
                                  r'"@timestamp": "PYCSW_TIMESTAMP"')
    # harvesting-based GetRecords/GetRecordById responses
    if normalize_identifiers:
        dcid = re.findall(
            r'<dc:identifier>(urn:uuid.*)</dc:identifier>',
            sresult
        )
        isoid = re.findall(r'id="(urn:uuid.*)"', sresult)
        isoid2 = re.findall(
            r'<gco:CharacterString>(urn:uuid.*)</gco',
            sresult
        )
        for d in dcid:
            sresult = sresult.replace(d, r'PYCSW_IDENTIFIER')
        for i in isoid:
            sresult = sresult.replace(i, r'PYCSW_IDENTIFIER')
        for i2 in isoid2:
            sresult = sresult.replace(i2, r'PYCSW_IDENTIFIER')
    return sresult