#!/usr/bin/env python3

"""Edit test cases to use PSA dependencies instead of classic dependencies.
"""

# Copyright The Mbed TLS Contributors
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import re
import sys

CLASSIC_DEPENDENCIES = frozenset([
    # This list is manually filtered from config.h.

    # Mbed TLS feature support.
    # Only features that affect what can be done are listed here.
    # Options that control optimizations or alternative implementations
    # are omitted.
    #cipher#'MBEDTLS_CIPHER_MODE_CBC',
    #cipher#'MBEDTLS_CIPHER_MODE_CFB',
    #cipher#'MBEDTLS_CIPHER_MODE_CTR',
    #cipher#'MBEDTLS_CIPHER_MODE_OFB',
    #cipher#'MBEDTLS_CIPHER_MODE_XTS',
    #cipher#'MBEDTLS_CIPHER_NULL_CIPHER',
    #cipher#'MBEDTLS_CIPHER_PADDING_PKCS7',
    #cipher#'MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS',
    #cipher#'MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN',
    #cipher#'MBEDTLS_CIPHER_PADDING_ZEROS',
    #curve#'MBEDTLS_ECP_DP_SECP192R1_ENABLED',
    #curve#'MBEDTLS_ECP_DP_SECP224R1_ENABLED',
    #curve#'MBEDTLS_ECP_DP_SECP256R1_ENABLED',
    #curve#'MBEDTLS_ECP_DP_SECP384R1_ENABLED',
    #curve#'MBEDTLS_ECP_DP_SECP521R1_ENABLED',
    #curve#'MBEDTLS_ECP_DP_SECP192K1_ENABLED',
    #curve#'MBEDTLS_ECP_DP_SECP224K1_ENABLED',
    #curve#'MBEDTLS_ECP_DP_SECP256K1_ENABLED',
    #curve#'MBEDTLS_ECP_DP_BP256R1_ENABLED',
    #curve#'MBEDTLS_ECP_DP_BP384R1_ENABLED',
    #curve#'MBEDTLS_ECP_DP_BP512R1_ENABLED',
    #curve#'MBEDTLS_ECP_DP_CURVE25519_ENABLED',
    #curve#'MBEDTLS_ECP_DP_CURVE448_ENABLED',
    'MBEDTLS_ECDSA_DETERMINISTIC',
    #'MBEDTLS_GENPRIME', #needed for RSA key generation
    'MBEDTLS_PKCS1_V15',
    'MBEDTLS_PKCS1_V21',
    'MBEDTLS_SHA512_NO_SHA384',

    # Mbed TLS modules.
    # Only modules that provide cryptographic mechanisms are listed here.
    # Platform, data formatting, X.509 or TLS modules are omitted.
    #cipher#'MBEDTLS_AES_C',
    #cipher#'MBEDTLS_ARC4_C',
    'MBEDTLS_BIGNUM_C',
    #cipher#'MBEDTLS_BLOWFISH_C',
    #cipher#'MBEDTLS_CAMELLIA_C',
    #cipher#'MBEDTLS_ARIA_C',
    #cipher#'MBEDTLS_CCM_C',
    #cipher#'MBEDTLS_CHACHA20_C',
    #cipher#'MBEDTLS_CHACHAPOLY_C',
    #cipher#'MBEDTLS_CMAC_C',
    'MBEDTLS_CTR_DRBG_C',
    #cipher#'MBEDTLS_DES_C',
    'MBEDTLS_DHM_C',
    'MBEDTLS_ECDH_C',
    'MBEDTLS_ECDSA_C',
    'MBEDTLS_ECJPAKE_C',
    'MBEDTLS_ECP_C',
    'MBEDTLS_ENTROPY_C',
    #cipher#'MBEDTLS_GCM_C',
    'MBEDTLS_HKDF_C',
    'MBEDTLS_HMAC_DRBG_C',
    #cipher#'MBEDTLS_NIST_KW_C',
    'MBEDTLS_MD2_C',
    'MBEDTLS_MD4_C',
    'MBEDTLS_MD5_C',
    'MBEDTLS_PKCS5_C',
    'MBEDTLS_PKCS12_C',
    #cipher#'MBEDTLS_POLY1305_C',
    #cipher#'MBEDTLS_RIPEMD160_C',
    'MBEDTLS_RSA_C',
    'MBEDTLS_SHA1_C',
    'MBEDTLS_SHA256_C',
    'MBEDTLS_SHA512_C',
    'MBEDTLS_XTEA_C',
])

def is_classic_dependency(dep):
    """Whether dep is a classic dependency that PSA test cases should not use."""
    if dep.startswith('!'):
        dep = dep[1:]
    return dep in CLASSIC_DEPENDENCIES

def is_systematic_dependency(dep):
    """Whether dep is a PSA dependency which is determined systematically."""
    return dep.startswith('PSA_WANT_')

WITHOUT_SYSTEMATIC_DEPENDENCIES = frozenset([
    'PSA_ALG_AEAD_WITH_SHORTENED_TAG', # only a modifier
    'PSA_ALG_ANY_HASH', # only meaningful in policies
    'PSA_ALG_KEY_AGREEMENT', # only a way to combine algorithms
    'PSA_ALG_TRUNCATED_MAC', # only a modifier
    'PSA_KEY_TYPE_NONE', # not a real key type
    'PSA_KEY_TYPE_DERIVE', # always supported, don't list it to reduce noise
    'PSA_KEY_TYPE_RAW_DATA', # always supported, don't list it to reduce noise
    'PSA_ALG_AT_LEAST_THIS_LENGTH_MAC', #only a modifier
    'PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG', #only a modifier

    # Not implemented yet: cipher-related key types and algorithms.
    # Manually extracted from crypto_values.h.
    'PSA_KEY_TYPE_AES',
    'PSA_KEY_TYPE_DES',
    'PSA_KEY_TYPE_CAMELLIA',
    'PSA_KEY_TYPE_ARC4',
    'PSA_KEY_TYPE_CHACHA20',
    'PSA_ALG_CBC_MAC',
    'PSA_ALG_CMAC',
    'PSA_ALG_STREAM_CIPHER',
    'PSA_ALG_CTR',
    'PSA_ALG_CFB',
    'PSA_ALG_OFB',
    'PSA_ALG_XTS',
    'PSA_ALG_ECB_NO_PADDING',
    'PSA_ALG_CBC_NO_PADDING',
    'PSA_ALG_CBC_PKCS7',
    'PSA_ALG_CCM',
    'PSA_ALG_GCM',
    'PSA_ALG_CHACHA20_POLY1305',
])

SPECIAL_SYSTEMATIC_DEPENDENCIES = {
    'PSA_ALG_ECDSA_ANY': frozenset(['PSA_WANT_ALG_ECDSA']),
    'PSA_ALG_RSA_PKCS1V15_SIGN_RAW': frozenset(['PSA_WANT_ALG_RSA_PKCS1V15_SIGN']),
}

def dependencies_of_symbol(symbol):
    """Return the dependencies for a symbol that designates a cryptographic mechanism."""
    if symbol in WITHOUT_SYSTEMATIC_DEPENDENCIES:
        return frozenset()
    if symbol in SPECIAL_SYSTEMATIC_DEPENDENCIES:
        return SPECIAL_SYSTEMATIC_DEPENDENCIES[symbol]
    if symbol.startswith('PSA_ALG_CATEGORY_') or \
       symbol.startswith('PSA_KEY_TYPE_CATEGORY_'):
        # Categories are used in test data when an unsupported but plausible
        # mechanism number needed. They have no associated dependency.
        return frozenset()
    return {symbol.replace('_', '_WANT_', 1)}

def systematic_dependencies(file_name, function_name, arguments):
    """List the systematically determined dependency for a test case."""
    deps = set()

    # Run key policy negative tests even if the algorithm to attempt performing
    # is not supported.
    if function_name.endswith('_key_policy') and \
       arguments[-1].startswith('PSA_ERROR_'):
        arguments[-2] = ''
    if function_name == 'copy_fail' and \
       arguments[-1].startswith('PSA_ERROR_'):
        arguments[-2] = ''
        arguments[-3] = ''

    # Storage format tests that only look at how the file is structured and
    # don't care about the format of the key material don't depend on any
    # cryptographic mechanisms.
    if os.path.basename(file_name) == 'test_suite_psa_crypto_persistent_key.data' and \
       function_name in {'format_storage_data_check',
                         'parse_storage_data_check'}:
        return []

    for arg in arguments:
        for symbol in re.findall(r'PSA_(?:ALG|KEY_TYPE)_\w+', arg):
            deps.update(dependencies_of_symbol(symbol))
    return sorted(deps)

def updated_dependencies(file_name, function_name, arguments, dependencies):
    """Rework the list of dependencies into PSA_WANT_xxx.

    Remove classic crypto dependencies such as MBEDTLS_RSA_C,
    MBEDTLS_PKCS1_V15, etc.

    Add systematic PSA_WANT_xxx dependencies based on the called function and
    its arguments, replacing existing PSA_WANT_xxx dependencies.
    """
    automatic = systematic_dependencies(file_name, function_name, arguments)
    manual = [dep for dep in dependencies
              if not (is_systematic_dependency(dep) or
                      is_classic_dependency(dep))]
    return automatic + manual

def keep_manual_dependencies(file_name, function_name, arguments):
    #pylint: disable=unused-argument
    """Declare test functions with unusual dependencies here."""
    # If there are no arguments, we can't do any useful work. Assume that if
    # there are dependencies, they are warranted.
    if not arguments:
        return True
    # When PSA_ERROR_NOT_SUPPORTED is expected, usually, at least one of the
    # constants mentioned in the test should not be supported. It isn't
    # possible to determine which one in a systematic way. So let the programmer
    # decide.
    if arguments[-1] == 'PSA_ERROR_NOT_SUPPORTED':
        return True
    return False

def process_data_stanza(stanza, file_name, test_case_number):
    """Update PSA crypto dependencies in one Mbed TLS test case.

    stanza is the test case text (including the description, the dependencies,
    the line with the function and arguments, and optionally comments). Return
    a new stanza with an updated dependency line, preserving everything else
    (description, comments, arguments, etc.).
    """
    if not stanza.lstrip('\n'):
        # Just blank lines
        return stanza
    # Expect 2 or 3 non-comment lines: description, optional dependencies,
    # function-and-arguments.
    content_matches = list(re.finditer(r'^[\t ]*([^\t #].*)$', stanza, re.M))
    if len(content_matches) < 2:
        raise Exception('Not enough content lines in paragraph {} in {}'
                        .format(test_case_number, file_name))
    if len(content_matches) > 3:
        raise Exception('Too many content lines in paragraph {} in {}'
                        .format(test_case_number, file_name))
    arguments = content_matches[-1].group(0).split(':')
    function_name = arguments.pop(0)
    if keep_manual_dependencies(file_name, function_name, arguments):
        return stanza
    if len(content_matches) == 2:
        # Insert a line for the dependencies. If it turns out that there are
        # no dependencies, we'll remove that empty line below.
        dependencies_location = content_matches[-1].start()
        text_before = stanza[:dependencies_location]
        text_after = '\n' + stanza[dependencies_location:]
        old_dependencies = []
        dependencies_leader = 'depends_on:'
    else:
        dependencies_match = content_matches[-2]
        text_before = stanza[:dependencies_match.start()]
        text_after = stanza[dependencies_match.end():]
        old_dependencies = dependencies_match.group(0).split(':')
        dependencies_leader = old_dependencies.pop(0) + ':'
        if dependencies_leader != 'depends_on:':
            raise Exception('Next-to-last line does not start with "depends_on:"'
                            ' in paragraph {} in {}'
                            .format(test_case_number, file_name))
    new_dependencies = updated_dependencies(file_name, function_name, arguments,
                                            old_dependencies)
    if new_dependencies:
        stanza = (text_before +
                  dependencies_leader + ':'.join(new_dependencies) +
                  text_after)
    else:
        # The dependencies have become empty. Remove the depends_on: line.
        assert text_after[0] == '\n'
        stanza = text_before + text_after[1:]
    return stanza

def process_data_file(file_name, old_content):
    """Update PSA crypto dependencies in an Mbed TLS test suite data file.

    Process old_content (the old content of the file) and return the new content.
    """
    old_stanzas = old_content.split('\n\n')
    new_stanzas = [process_data_stanza(stanza, file_name, n)
                   for n, stanza in enumerate(old_stanzas, start=1)]
    return '\n\n'.join(new_stanzas)

def update_file(file_name, old_content, new_content):
    """Update the given file with the given new content.

    Replace the existing file. The previous version is renamed to *.bak.
    Don't modify the file if the content was unchanged.
    """
    if new_content == old_content:
        return
    backup = file_name + '.bak'
    tmp = file_name + '.tmp'
    with open(tmp, 'w', encoding='utf-8') as new_file:
        new_file.write(new_content)
    os.replace(file_name, backup)
    os.replace(tmp, file_name)

def process_file(file_name):
    """Update PSA crypto dependencies in an Mbed TLS test suite data file.

    Replace the existing file. The previous version is renamed to *.bak.
    Don't modify the file if the content was unchanged.
    """
    old_content = open(file_name, encoding='utf-8').read()
    if file_name.endswith('.data'):
        new_content = process_data_file(file_name, old_content)
    else:
        raise Exception('File type not recognized: {}'
                        .format(file_name))
    update_file(file_name, old_content, new_content)

def main(args):
    for file_name in args:
        process_file(file_name)

if __name__ == '__main__':
    main(sys.argv[1:])
