import re


def ecm_kw_regex_select(ecm_names_list, list_of_match_str):
    """Identify matching, non-matching ECM names using a list of search terms

    This function searches a list of ECM names to find all of the ECM
    names that have the words specified by the user as search terms.
    This function is used to identify the ECMs that should be moved from
    the active to inactive list or vice versa. The regex is set up to
    be case-insensitive.

    Args:
        ecm_names_list (list): A list of ECM names encoded as strings.
        list_of_match_str (list): A list with at least one entry,
            corresponding to the strings specified by the user to
            be used to select ECMs to move from the active to the
            inactive list, or vice versa.

    Returns:
        A list of all of the ECM names that matched with the search
        string(s) and a separate list of all of the ECM names that did
        not match with the search string.
    """

    # If the list is not empty, identify the matching and non-matching
    # entries in the list of ECM names
    if list_of_match_str:
        # Construct the regex search pattern from the list of strings given
        nom_regex = re.compile(r'(?:%s)' % '|'.join(list_of_match_str),
                               re.IGNORECASE).search
        # Construct the inverse regex search pattern from list of strings given
        nom_regex_inv = re.compile(r'(?:%s)' % '|'.join([
            x.strip("! ") for x in list_of_match_str if "!" in x]),
            re.IGNORECASE).search

        # Construct a list of all of the ECM names that matched the regex
        matches = [ecm for ecm in ecm_names_list if nom_regex(ecm)]
        # Construct list of all ECM names that matched the inverse regex
        matches_inv = [ecm for ecm in ecm_names_list if nom_regex_inv(ecm)]
        # Add all ECMs that do NOT match the inverse regex search term(s) to
        # the list of matched ECMs
        if len(matches_inv) > 0:
            matches.extend([x for x in ecm_names_list if (
                x not in matches_inv and x not in matches)])
        # Construct list of all ECM names that were not matched
        non_matches = [ecm for ecm in ecm_names_list if ecm not in matches]

    # If the list is empty, running the above process would result in
    # all of the ECM names matching, which is the opposite of what is
    # desired for the case with no keywords, thus this case of no
    # search terms is handled explicitly
    else:
        matches = []
        non_matches = ecm_names_list

    return matches, non_matches