"""
Translates a SeleniumBase Python file into a different language

Usage:
        seleniumbase translate [SB_FILE.py] [LANGUAGE] [ACTION]
        OR:    sbase translate [SB_FILE.py] [LANGUAGE] [ACTION]
Languages:
        --en / --English    |    --zh / --Chinese
        --nl / --Dutch      |    --fr / --French
        --it / --Italian    |    --ja / --Japanese
        --ko / --Korean     |    --pt / --Portuguese
        --ru / --Russian    |    --es / --Spanish
Actions:
        -p / --print  (Print translation output to the screen)
        -o / --overwrite  (Overwrite the file being translated)
        -c / --copy  (Copy the translation to a new .py file)
Options:
        -n  (include line Numbers when using the Print action)
Output:
        Translates a SeleniumBase Python file into the language
        specified. Method calls and "import" lines get swapped.
        Both a language and an action must be specified.
        The "-p" action can be paired with one other action.
        When running with "-c" (or "--copy"), the new file name
        will be the original name appended with an underscore
        plus the 2-letter language code of the new language.
        (Example: Translating "test_1.py" into Japanese with
        "-c" will create a new file called "test_1_ja.py".)
"""
import colorama
import os
import re
import sys
from seleniumbase.translate import master_dict

MD_F = master_dict.MD_F
MD_L_Codes = master_dict.MD_L_Codes
MD = master_dict.MD


def invalid_run_command(msg=None):
    exp = "  ** translate **\n\n"
    exp += "  Usage:\n"
    exp += "         seleniumbase translate [SB_FILE.py] [LANGUAGE] [ACTION]\n"
    exp += "         OR:    sbase translate [SB_FILE.py] [LANGUAGE] [ACTION]\n"
    exp += "  Languages:\n"
    exp += "         --en / --English    |    --zh / --Chinese\n"
    exp += "         --nl / --Dutch      |    --fr / --French\n"
    exp += "         --it / --Italian    |    --ja / --Japanese\n"
    exp += "         --ko / --Korean     |    --pt / --Portuguese\n"
    exp += "         --ru / --Russian    |    --es / --Spanish\n"
    exp += "  Actions:\n"
    exp += "         -p / --print  (Print translation output to the screen)\n"
    exp += "         -o / --overwrite  (Overwrite the file being translated)\n"
    exp += "         -c / --copy  (Copy the translation to a new .py file)\n"
    exp += "  Options:\n"
    exp += "         -n  (include line Numbers when using the Print action)\n"
    exp += "  Output:\n"
    exp += "         Translates a SeleniumBase Python file into the language\n"
    exp += '         specified. Method calls and "import" lines get swapped.\n'
    exp += "         Both a language and an action must be specified.\n"
    exp += '         The "-p" action can be paired with one other action.\n'
    exp += '         When running with "-c" (or "--copy"), the new file name\n'
    exp += "         will be the original name appended with an underscore\n"
    exp += "         plus the 2-letter language code of the new language.\n"
    exp += '         (Example: Translating "test_1.py" into Japanese with\n'
    exp += '          "-c" will create a new file called "test_1_ja.py".)\n'
    if not msg:
        raise Exception("INVALID RUN COMMAND!\n\n%s" % exp)
    else:
        raise Exception("INVALID RUN COMMAND!\n%s\n\n%s" % (msg, exp))


def sc_ranges():
    # Get the ranges of special double-width characters.
    special_char_ranges = [
        {"from": ord("\u4e00"), "to": ord("\u9FFF")},
        {"from": ord("\u3040"), "to": ord("\u30ff")},
        {"from": ord("\uac00"), "to": ord("\ud7a3")},
        {"from": ord("\uff01"), "to": ord("\uff60")},
    ]
    return special_char_ranges


def is_cjk(char):
    # Returns True if the special character is Chinese, Japanese, or Korean.
    sc = any(
        [range["from"] <= ord(char) <= range["to"] for range in sc_ranges()]
    )
    return sc


def get_width(line):
    # Return the true width of the line. Not the same as line length.
    # Chinese/Japanese/Korean characters take up double width visually.
    line_length = len(line)
    for char in line:
        if is_cjk(char):
            line_length += 1
    return line_length


def process_test_file(code_lines, new_lang):
    detected_lang = None
    changed = False
    found_bc = False  # Found BaseCase or a translation
    seleniumbase_lines = []
    lang_codes = MD_L_Codes.lang
    nl_code = lang_codes[new_lang]  # new_lang language code
    dl_code = None  # detected_lang language code
    md = MD.md  # Master Dictionary

    for line in code_lines:
        line = line.rstrip()

        # Find imports that determine the language
        if line.lstrip().startswith("from seleniumbase") and "import" in line:
            added_line = False
            for lang in MD_F.get_languages_list():
                data = re.match(
                    r"^\s*" + MD_F.get_import_line(lang) + r"([\S\s]*)$", line
                )
                if data:
                    comments = "%s" % data.group(1)
                    new_line = None
                    detected_lang = lang
                    dl_code = lang_codes[detected_lang]
                    if detected_lang != new_lang:
                        changed = True
                        new_line = MD_F.get_import_line(new_lang) + comments
                    else:
                        found_bc = True
                        new_line = line
                    if new_line.endswith("  # noqa"):  # Remove flake8 skip
                        new_line = new_line[0 : -len("  # noqa")]
                    seleniumbase_lines.append(new_line)
                    added_line = True
                    break
                data = re.match(
                    r"^\s*" + MD_F.get_mqa_im_line(lang) + r"([\S\s]*)$", line
                )
                if data:
                    comments = "%s" % data.group(1)
                    new_line = None
                    detected_lang = lang
                    dl_code = lang_codes[detected_lang]
                    if detected_lang != new_lang:
                        changed = True
                        new_line = MD_F.get_mqa_im_line(new_lang) + comments
                    else:
                        found_bc = True
                        new_line = line
                    if new_line.endswith("  # noqa"):  # Remove flake8 skip
                        new_line = new_line[0 : -len("  # noqa")]
                    seleniumbase_lines.append(new_line)
                    added_line = True
                    break
            if not added_line:
                # Probably a language missing from the translator.
                # Add the import line as it is and move on.
                seleniumbase_lines.append(line)
            continue

        # Find class definitions that determine the language
        if line.lstrip().startswith("class ") and ":" in line:
            added_line = False
            data = re.match(
                r"""^(\s*)class\s+([\S]+)\(([\S]+)\):([\S\s]*)$""", line
            )
            if data:
                whitespace = data.group(1)
                name = "%s" % data.group(2)
                parent_class = "%s" % data.group(3)
                comments = "%s" % data.group(4)
                if parent_class in MD_F.get_parent_classes_list():
                    detected_lang = MD_F.get_parent_class_lang(parent_class)
                    dl_code = lang_codes[detected_lang]
                    if detected_lang != new_lang:
                        changed = True
                        new_parent = MD_F.get_lang_parent_class(new_lang)
                        new_line = "%sclass %s(%s):%s" "" % (
                            whitespace,
                            name,
                            new_parent,
                            comments,
                        )
                    else:
                        found_bc = True
                        new_line = line
                    if new_line.endswith("  # noqa"):  # Remove flake8 skip
                        new_line = new_line[0 : -len("  # noqa")]
                    seleniumbase_lines.append(new_line)
                    added_line = True
                    continue
                elif parent_class in MD_F.get_masterqa_parent_classes_list():
                    detected_lang = MD_F.get_mqa_par_class_lang(parent_class)
                    dl_code = lang_codes[detected_lang]
                    if detected_lang != new_lang:
                        changed = True
                        new_parent = MD_F.get_mqa_lang_par_class(new_lang)
                        new_line = "%sclass %s(%s):%s" "" % (
                            whitespace,
                            name,
                            new_parent,
                            comments,
                        )
                    else:
                        found_bc = True
                        new_line = line
                    if new_line.endswith("  # noqa"):  # Remove flake8 skip
                        new_line = new_line[0 : -len("  # noqa")]
                    seleniumbase_lines.append(new_line)
                    added_line = True
                    continue
            if not added_line:
                # Probably a language missing from the translator.
                # Add the class definition line as it is and move on.
                seleniumbase_lines.append(line)
            continue

        if (
            ".main(__name__, __file__)" in line
            and detected_lang
            and new_lang
            and (detected_lang != new_lang)
        ):
            old_basecase = MD_F.get_lang_parent_class(detected_lang)
            new_basecase = MD_F.get_lang_parent_class(new_lang)
            if old_basecase in line:
                new_line = line.replace(old_basecase, new_basecase)
                seleniumbase_lines.append(new_line)
                continue

        if (
            "self." in line
            and "(" in line
            and detected_lang
            and (detected_lang != new_lang)
        ):
            found_swap = False
            replace_count = line.count("self.")  # Total possible replacements
            for key in md.keys():
                original = "self." + md[key][dl_code] + "("
                if original in line:
                    replacement = "self." + md[key][nl_code] + "("
                    new_line = line.replace(original, replacement)
                    found_swap = True
                    replace_count -= 1
                    if replace_count == 0:
                        break  # Done making replacements
                    else:
                        # There might be another method to replace in the line.
                        # Example: self.assert_true("Name" in self.get_title())
                        line = new_line
                        continue

            if found_swap:
                if new_line.endswith("  # noqa"):  # Remove flake8 skip
                    new_line = new_line[0 : -len("  # noqa")]
                seleniumbase_lines.append(new_line)
                continue

        seleniumbase_lines.append(line)

    return seleniumbase_lines, changed, detected_lang, found_bc


def main():
    c1 = colorama.Fore.BLUE + colorama.Back.LIGHTCYAN_EX
    c2 = colorama.Fore.BLUE + colorama.Back.LIGHTYELLOW_EX
    c3 = colorama.Fore.RED + colorama.Back.LIGHTGREEN_EX
    c4 = colorama.Fore.BLUE + colorama.Back.LIGHTGREEN_EX
    c5 = colorama.Fore.RED + colorama.Back.LIGHTYELLOW_EX
    c6 = colorama.Fore.RED + colorama.Back.LIGHTCYAN_EX
    c7 = colorama.Fore.BLACK + colorama.Back.MAGENTA
    cr = colorama.Style.RESET_ALL
    new_lang = None
    overwrite = False
    copy = False
    print_only = False
    help_me = False
    invalid_cmd = None
    line_numbers = False
    word_wrap = True  # Always use word wrap now

    expected_arg = "A SeleniumBase Python file"
    command_args = sys.argv[2:]
    seleniumbase_file = command_args[0]
    if not seleniumbase_file.endswith(".py"):
        seleniumbase_file = (
            c7 + ">>" + c5 + " " + seleniumbase_file + " " + c7 + "<<" + cr
        )
        bad_file_error = (
            "\n`%s` is not a Python file!\n\n"
            "Expecting: [%s]" % (seleniumbase_file, expected_arg)
        )
        bad_file_error = bad_file_error.replace(
            "is not a Python file!", c3 + "is not a Python file!" + cr
        )
        bad_file_error = bad_file_error.replace(
            expected_arg, c4 + expected_arg + cr
        )
        bad_file_error = bad_file_error.replace(
            "Expecting:", c3 + "Expecting:" + cr
        )
        print(bad_file_error)
        help_me = True

    if len(command_args) >= 2 and not help_me:
        options = command_args[1:]
        for option in options:
            option = option.lower()
            if option == "help" or option == "--help":
                help_me = True
            elif option == "-o" or option == "--overwrite":
                overwrite = True
            elif option == "-c" or option == "--copy":
                copy = True
            elif option == "-p" or option == "--print":
                print_only = True
            elif option == "-n":
                line_numbers = True
            elif option == "--en" or option == "--english":
                new_lang = "English"
            elif option == "--zh" or option == "--chinese":
                new_lang = "Chinese"
            elif option == "--nl" or option == "--dutch":
                new_lang = "Dutch"
            elif option == "--fr" or option == "--french":
                new_lang = "French"
            elif option == "--it" or option == "--italian":
                new_lang = "Italian"
            elif option == "--ja" or option == "--japanese":
                new_lang = "Japanese"
            elif option == "--ko" or option == "--korean":
                new_lang = "Korean"
            elif option == "--pt" or option == "--portuguese":
                new_lang = "Portuguese"
            elif option == "--ru" or option == "--russian":
                new_lang = "Russian"
            elif option == "--es" or option == "--spanish":
                new_lang = "Spanish"
            else:
                invalid_cmd = "\n===> INVALID OPTION: >> %s <<\n" % option
                invalid_cmd = invalid_cmd.replace(">> ", ">>" + c5 + " ")
                invalid_cmd = invalid_cmd.replace(" <<", " " + cr + "<<")
                invalid_cmd = invalid_cmd.replace(">>", c7 + ">>" + cr)
                invalid_cmd = invalid_cmd.replace("<<", c7 + "<<" + cr)
                help_me = True
                break
    else:
        help_me = True

    specify_lang = (
        "\n>* You must specify a language to translate to! *<\n"
        "\n"
        ">    ********  Language Options:  ********    <\n"
        "   --en / --English    |    --zh / --Chinese\n"
        "   --nl / --Dutch      |    --fr / --French\n"
        "   --it / --Italian    |    --ja / --Japanese\n"
        "   --ko / --Korean     |    --pt / --Portuguese\n"
        "   --ru / --Russian    |    --es / --Spanish\n"
    )
    specify_action = (
        "\n>* You must specify an action type! *<\n"
        "\n"
        "> *** Action Options: *** <\n"
        "      -p / --print\n"
        "      -o / --overwrite\n"
        "      -c / --copy\n"
    )
    example_run = (
        "\n> *** Examples: *** <\n"
        "Translate test_1.py into Chinese and only print the output:\n"
        " >$ sbase translate test_1.py --zh -p\n"
        "Translate test_2.py into Portuguese and overwrite the file:\n"
        " >$ sbase translate test_2.py --pt -o\n"
        "Translate test_3.py into Dutch and make a copy of the file:\n"
        " >$ sbase translate test_3.py --nl -c\n"
    )
    usage = (
        "\n> *** Usage: *** <\n"
        " >$ sbase translate [SB_FILE.py] [LANGUAGE] [ACTION]\n"
    )
    specify_lang = specify_lang.replace(">*", c5 + ">*")
    specify_lang = specify_lang.replace("*<", "*<" + cr)
    specify_lang = specify_lang.replace(
        "Language Options:", c4 + "Language Options:" + cr
    )
    specify_lang = specify_lang.replace(
        ">    ********  ", c3 + ">    ********  " + cr
    )
    specify_lang = specify_lang.replace(
        "  ********    <", c3 + "  ********    <" + cr
    )
    specify_lang = specify_lang.replace("--en", c2 + "--en" + cr)
    specify_lang = specify_lang.replace("--zh", c2 + "--zh" + cr)
    specify_lang = specify_lang.replace("--nl", c2 + "--nl" + cr)
    specify_lang = specify_lang.replace("--fr", c2 + "--fr" + cr)
    specify_lang = specify_lang.replace("--it", c2 + "--it" + cr)
    specify_lang = specify_lang.replace("--ja", c2 + "--ja" + cr)
    specify_lang = specify_lang.replace("--ko", c2 + "--ko" + cr)
    specify_lang = specify_lang.replace("--pt", c2 + "--pt" + cr)
    specify_lang = specify_lang.replace("--ru", c2 + "--ru" + cr)
    specify_lang = specify_lang.replace("--es", c2 + "--es" + cr)
    specify_lang = specify_lang.replace("--English", c2 + "--English" + cr)
    specify_lang = specify_lang.replace("--Chinese", c2 + "--Chinese" + cr)
    specify_lang = specify_lang.replace("--Dutch", c2 + "--Dutch" + cr)
    specify_lang = specify_lang.replace("--French", c2 + "--French" + cr)
    specify_lang = specify_lang.replace("--Italian", c2 + "--Italian" + cr)
    specify_lang = specify_lang.replace("--Japanese", c2 + "--Japanese" + cr)
    specify_lang = specify_lang.replace("--Korean", c2 + "--Korean" + cr)
    specify_lang = specify_lang.replace(
        "--Portuguese", c2 + "--Portuguese" + cr
    )
    specify_lang = specify_lang.replace("--Russian", c2 + "--Russian" + cr)
    specify_lang = specify_lang.replace("--Spanish", c2 + "--Spanish" + cr)
    specify_action = specify_action.replace(">*", c6 + ">*")
    specify_action = specify_action.replace("*<", "*<" + cr)
    specify_action = specify_action.replace(
        "Action Options:", c4 + "Action Options:" + cr
    )
    specify_action = specify_action.replace("> *** ", c3 + "> *** " + cr)
    specify_action = specify_action.replace(" *** <", c3 + " *** <" + cr)
    specify_action = specify_action.replace(" -p", " " + c1 + "-p" + cr)
    specify_action = specify_action.replace(" -o", " " + c1 + "-o" + cr)
    specify_action = specify_action.replace(" -c", " " + c1 + "-c" + cr)
    specify_action = specify_action.replace(
        " --print", " " + c1 + "--print" + cr
    )
    specify_action = specify_action.replace(
        " --overwrite", " " + c1 + "--overwrite" + cr
    )
    specify_action = specify_action.replace(
        " --copy", " " + c1 + "--copy" + cr
    )
    example_run = example_run.replace("Examples:", c4 + "Examples:" + cr)
    example_run = example_run.replace("> *** ", c3 + "> *** " + cr)
    example_run = example_run.replace(" *** <", c3 + " *** <" + cr)
    example_run = example_run.replace(" -p", " " + c1 + "-p" + cr)
    example_run = example_run.replace(" -o", " " + c1 + "-o" + cr)
    example_run = example_run.replace(" -c", " " + c1 + "-c" + cr)
    example_run = example_run.replace("Chinese", c2 + "Chinese" + cr)
    example_run = example_run.replace("Portuguese", c2 + "Portuguese" + cr)
    example_run = example_run.replace("Dutch", c2 + "Dutch" + cr)
    example_run = example_run.replace(" --zh", " " + c2 + "--zh" + cr)
    example_run = example_run.replace(" --pt", " " + c2 + "--pt" + cr)
    example_run = example_run.replace(" --nl", " " + c2 + "--nl" + cr)
    example_run = example_run.replace("sbase", c4 + "sbase" + cr)
    usage = usage.replace("Usage:", c4 + "Usage:" + cr)
    usage = usage.replace("> *** ", c3 + "> *** " + cr)
    usage = usage.replace(" *** <", c3 + " *** <" + cr)
    usage = usage.replace("SB_FILE.py", c4 + "SB_FILE.py" + cr)
    usage = usage.replace("LANGUAGE", c2 + "LANGUAGE" + cr)
    usage = usage.replace("ACTION", c1 + "ACTION" + cr)

    if help_me:
        message = ""
        if invalid_cmd:
            message += invalid_cmd
        message += specify_lang + specify_action + example_run + usage
        print("")
        raise Exception(message)
    if not overwrite and not copy and not print_only:
        message = specify_action + example_run + usage
        if not new_lang:
            message = specify_lang + specify_action + example_run + usage
        print("")
        raise Exception(message)
    if not new_lang:
        print("")
        raise Exception(specify_lang + example_run + usage)
    if overwrite and copy:
        part_1 = (
            "\n* You can choose either {-o / --overwrite} "
            "OR {-c / --copy}, BUT * NOT BOTH *!\n"
        )
        part_1 = part_1.replace("-o ", c1 + "-o" + cr + " ")
        part_1 = part_1.replace("--overwrite", c1 + "--overwrite" + cr)
        part_1 = part_1.replace("-c ", c1 + "-c" + cr + " ")
        part_1 = part_1.replace("--copy", c1 + "--copy" + cr)
        part_1 = part_1.replace("* NOT BOTH *", c6 + "* NOT BOTH *" + cr)
        message = part_1 + example_run + usage
        print("")
        raise Exception(message)

    with open(seleniumbase_file, mode="r", encoding="utf-8") as f:
        all_code = f.read()
    if "def test_" not in all_code and "from seleniumbase" not in all_code:
        print("")
        raise Exception(
            "\n\n`%s` is not a valid SeleniumBase test file!\n"
            "\nExpecting: [%s]\n" % (seleniumbase_file, expected_arg)
        )
    all_code = all_code.replace("\t", "    ")
    code_lines = all_code.split("\n")

    sb_lines, changed, d_l, found_bc = process_test_file(code_lines, new_lang)
    seleniumbase_lines = sb_lines
    detected_lang = d_l
    found_basecase = found_bc

    if not changed and found_basecase:
        print("")
        msg1 = " [[[[%s]]]] was already in [[[%s]]]!\n\n" "" % (
            seleniumbase_file,
            new_lang,
        )
        msg1 = msg1.replace("[[[[", "" + c3).replace("]]]]", cr + "")
        msg1 = msg1.replace("[[[", "" + c5).replace("]]]", cr + "")
        msg2 = None
        if print_only:
            msg2 = "*> ***  No changes to display!  *** <*"
        elif overwrite:
            msg2 = "*> ***  No changes were made!  *** <*"
        else:  # "copy" action
            msg2 = "*> ***  No action was taken!  *** <*"
        msg2 = msg2.replace("*>", " " + c6).replace("<*", cr + "\n")
        print(msg1 + msg2)
        return

    if not changed and not found_basecase:
        print("")
        filename = c3 + seleniumbase_file + cr
        from_sb = c5 + "from seleniumbase" + cr
        msg0 = " * In order to translate the script,\n"
        msg1 = ' %s requires "%s..."\n' % (filename, from_sb)
        msg2 = " and a BaseCase import in a supported language!\n\n"
        msg3 = None
        if print_only:
            msg3 = "*> ***  No changes to display!  *** <*"
        elif overwrite:
            msg3 = "*> ***  No changes were made!  *** <*"
        else:  # "copy" action
            msg3 = "*> ***  No action was taken!  *** <*"
        msg3 = msg3.replace("*>", " " + c6).replace("<*", cr + "\n")
        print(msg0 + msg1 + msg2 + msg3)
        return

    save_line = (
        " [[[[%s]]]] was translated to [[[%s]]]! "
        "(Previous: %s)\n"
        "" % (seleniumbase_file, new_lang, detected_lang)
    )
    save_line = save_line.replace("[[[[", "" + c4)
    save_line = save_line.replace("]]]]", cr + "")
    save_line = save_line.replace("[[[", "" + c2)
    save_line = save_line.replace("]]]", cr + "")

    if print_only:
        from rich.console import Console
        from rich.syntax import Syntax

        console_width = None  # width of console output when running script
        used_width = None  # code_width and few spaces on right for padding
        magic_console = None
        magic_syntax = None
        try:
            console_width = os.popen("stty size", "r").read().split()[1]
            if console_width:
                console_width = int(console_width)
        except Exception:
            console_width = None

        python_code = "\n".join(seleniumbase_lines)
        code_width = 1

        w = 0  # line number whitespace
        if line_numbers:
            w = 4
            num_lines = len(code_lines)
            if num_lines >= 10:
                w = 5
            if num_lines >= 100:
                w = 6
            if num_lines >= 1000:
                w = 7
            if num_lines >= 10000:
                w = 8

        new_sb_lines = []
        for line in seleniumbase_lines:
            if line.endswith("  # noqa") and line.count("  # noqa") == 1:
                line = line.replace("  # noqa", "")
            line_length2 = len(line)  # Normal Python string length used
            line_length = get_width(line)  # Special characters count 2X
            if line_length > code_width:
                code_width = line_length

            if console_width:
                # If line is larger than console_width, try to optimize it.
                # Smart Python word wrap to be used with valid indentation.
                if line_length + w > console_width:  # 5 is line number ws
                    if line.strip().startswith("#"):
                        new_sb_lines.append(line)
                        continue
                    elif (
                        line.count("  # ") == 1
                        and get_width(line.split("  # ")[0]) + w
                        <= console_width
                    ):
                        # Line is short enough once comment is removed
                        line = line.split("  # ")[0]
                        new_sb_lines.append(line)
                        continue
                    elif (
                        line.count(" # ") == 1
                        and get_width(line.split(" # ")[0]) + w
                        <= console_width
                    ):
                        # L-Length good if removing bad flake8 comment
                        line = line.split("  # ")[0]
                        new_sb_lines.append(line)
                        continue
                    if line.startswith("from") and " import " in line:
                        line1 = line.split(" import ")[0] + " \\"
                        line2 = "    import " + line.split(" import ")[1]
                        new_sb_lines.append(line1)
                        new_sb_lines.append(line2)
                        continue
                    if (
                        line.count("(") >= 1
                        and line.count("(") == line.count(")")
                    ):
                        whitespace = line_length2 - len(line.lstrip())
                        new_ws = line[0:whitespace] + "    "
                        first_paren = line.find("(")
                        line1 = line[:first_paren + 1]
                        line2 = new_ws + line[first_paren + 1:]
                        if ("):") not in line2:
                            new_sb_lines.append(line1)
                            if get_width(line2) + w > console_width:
                                if line2.count('", "') == 1:
                                    line2a = line2.split('", "')[0] + '",'
                                    line2b = (
                                        new_ws
                                        + '"'
                                        + (line2.split('", "')[1])
                                    )
                                    new_sb_lines.append(line2a)
                                    new_sb_lines.append(line2b)
                                    continue
                                elif line2.count("', '") == 1:
                                    line2a = line2.split("', '")[0] + "',"
                                    line2b = (
                                        new_ws
                                        + "'"
                                        + (line2.split("', '")[1])
                                    )
                                    new_sb_lines.append(line2a)
                                    new_sb_lines.append(line2b)
                                    continue
                                elif line2.count("://") == 1 and (
                                    line2.count('")') == 1
                                ):
                                    line2a = line2.split("://")[0] + '://"'
                                    line2b = (
                                        new_ws
                                        + '"'
                                        + (line2.split("://")[1])
                                    )
                                    new_sb_lines.append(line2a)
                                    if get_width(line2b) + w > (
                                        console_width
                                    ):
                                        if line2b.count("/") > 0:
                                            slash_one = line2b.find("/")
                                            slash_one_p1 = slash_one + 1
                                            line2b1 = (
                                                line2b[:slash_one_p1] + '"'
                                            )
                                            line2b2 = (
                                                new_ws
                                                + '"'
                                                + (line2b[slash_one_p1:])
                                            )
                                            new_sb_lines.append(line2b1)
                                            if line2b2.count(")  # ") == 1:
                                                line2b2 = (
                                                    line2b2.split(")  # ")[
                                                        0
                                                    ]
                                                    + ")"
                                                )
                                            new_sb_lines.append(line2b2)
                                            continue
                                    new_sb_lines.append(line2b)
                                    continue
                                elif line2.count("://") == 1 and (
                                    line2.count("')") == 1
                                ):
                                    line2a = line2.split("://")[0] + "://'"
                                    line2b = (
                                        new_ws
                                        + "'"
                                        + (line2.split("://")[1])
                                    )
                                    new_sb_lines.append(line2a)
                                    if get_width(line2b) + w > (
                                        console_width
                                    ):
                                        if line2b.count("/") > 0:
                                            slash_one = line2b.find("/")
                                            slash_one_p1 = slash_one + 1
                                            line2b1 = (
                                                line2b[:slash_one_p1] + "'"
                                            )
                                            line2b2 = (
                                                new_ws
                                                + "'"
                                                + (line2b[slash_one_p1:])
                                            )
                                            new_sb_lines.append(line2b1)
                                            if line2b2.count(")  # ") == 1:
                                                line2b2 = (
                                                    line2b2.split(")  # ")[
                                                        0
                                                    ]
                                                    + ")"
                                                )
                                            new_sb_lines.append(line2b2)
                                            continue
                                    new_sb_lines.append(line2b)
                                    continue
                                elif line2.count(", ") == 1:
                                    line2a = line2.split(", ")[0] + ","
                                    line2b = new_ws + line2.split(", ")[1]
                                    new_sb_lines.append(line2a)
                                    new_sb_lines.append(line2b)
                                    continue
                                elif line2.count('="') == 1 and (
                                    line2.lstrip().startswith("'")
                                ):
                                    line2a = line2.split('="')[0] + "='"
                                    line2b = (
                                        new_ws
                                        + "'\""
                                        + (line2.split('="')[1])
                                    )
                                    new_sb_lines.append(line2a)
                                    new_sb_lines.append(line2b)
                                    continue
                                elif line2.count("='") == 1 and (
                                    line2.lstrip().startswith('"')
                                ):
                                    line2a = line2.split("='")[0] + '="'
                                    line2b = (
                                        new_ws
                                        + "\"'"
                                        + (line2.split("='")[1])
                                    )
                                    new_sb_lines.append(line2a)
                                    new_sb_lines.append(line2b)
                                    continue
                            new_sb_lines.append(line2)
                        elif get_width(line2) + 4 + w <= console_width:
                            line2 = "    " + line2
                            new_sb_lines.append(line1)
                            new_sb_lines.append(line2)
                        else:
                            new_sb_lines.append(line)
                        continue
                    if line.count('("') == 1:
                        whitespace = line_length2 - len(line.lstrip())
                        new_ws = line[0:whitespace] + "    "
                        line1 = line.split('("')[0] + "("
                        line2 = new_ws + '"' + line.split('("')[1]
                        if ("):") not in line2:
                            new_sb_lines.append(line1)
                            if get_width(line2) + w > console_width:
                                if line2.count('" in self.') == 1:
                                    line2a = (
                                        line2.split('" in self.')[0]
                                        + '" in'
                                    )
                                    line2b = (
                                        new_ws
                                        + "self."
                                        + (line2.split('" in self.')[1])
                                    )
                                    new_sb_lines.append(line2a)
                                    new_sb_lines.append(line2b)
                                    continue
                            new_sb_lines.append(line2)
                        elif get_width(line2) + 4 + w <= console_width:
                            line2 = "    " + line2
                            new_sb_lines.append(line1)
                            new_sb_lines.append(line2)
                        else:
                            new_sb_lines.append(line)
                        continue
                    if line.count("('") == 1:
                        whitespace = line_length2 - len(line.lstrip())
                        new_ws = line[0:whitespace] + "    "
                        line1 = line.split("('")[0] + "("
                        line2 = new_ws + "'" + line.split("('")[1]
                        if ("):") not in line2:
                            new_sb_lines.append(line1)
                            if get_width(line2) + w > console_width:
                                if line2.count("' in self.") == 1:
                                    line2a = (
                                        line2.split("' in self.")[0]
                                        + "' in"
                                    )
                                    line2b = (
                                        new_ws
                                        + "self."
                                        + (line2.split("' in self.")[1])
                                    )
                                    new_sb_lines.append(line2a)
                                    new_sb_lines.append(line2b)
                                    continue
                            new_sb_lines.append(line2)
                        elif get_width(line2) + 4 + w <= console_width:
                            line2 = "    " + line2
                            new_sb_lines.append(line1)
                            new_sb_lines.append(line2)
                        else:
                            new_sb_lines.append(line)
                        continue
                    if line.count('= "') == 1 and line.count("://") == 1:
                        whitespace = line_length2 - len(line.lstrip())
                        new_ws = line[0:whitespace] + "    "
                        line1 = line.split("://")[0] + '://" \\'
                        line2 = new_ws + '"' + line.split("://")[1]
                        new_sb_lines.append(line1)
                        if get_width(line2) + w > console_width:
                            if line2.count("/") > 0:
                                slash_one = line2.find("/")
                                slash_one_p1 = slash_one + 1
                                line2a = line2[:slash_one_p1] + '" \\'
                                line2b = (
                                    new_ws + '"' + line2[slash_one_p1:]
                                )
                                new_sb_lines.append(line2a)
                                new_sb_lines.append(line2b)
                                continue
                        new_sb_lines.append(line2)
                        continue
                    if line.count("= '") == 1 and line.count("://") == 1:
                        whitespace = line_length2 - len(line.lstrip())
                        new_ws = line[0:whitespace] + "    "
                        line1 = line.split("://")[0] + "://' \\"
                        line2 = new_ws + "'" + line.split("://")[1]
                        new_sb_lines.append(line1)
                        if get_width(line2) + w > console_width:
                            if line2.count("/") > 0:
                                slash_one = line2.find("/")
                                slash_one_p1 = slash_one + 1
                                line2a = line2[:slash_one_p1] + "' \\"
                                line2b = (
                                    new_ws + "'" + line2[slash_one_p1:]
                                )
                                new_sb_lines.append(line2a)
                                new_sb_lines.append(line2b)
                                continue
                        new_sb_lines.append(line2)
                        continue
                    if line.count("(self.") == 1 and ("):") not in line:
                        whitespace = line_length2 - len(line.lstrip())
                        new_ws = line[0:whitespace] + "    "
                        line1 = line.split("(self.")[0] + "("
                        line2 = new_ws + "self." + line.split("(self.")[1]
                        if get_width(line1) + w <= console_width:
                            new_sb_lines.append(line1)
                            new_sb_lines.append(line2)
                            continue
                    if line.count(" == ") == 1 and not (
                        line.endswith(":") or (":  #") in line
                    ):
                        whitespace = line_length2 - len(line.lstrip())
                        new_ws = line[0:whitespace] + "    "
                        line1 = line.split(" == ")[0] + " == ("
                        line2 = new_ws + line.split(" == ")[1] + ")"
                        if get_width(line1) + w <= console_width and (
                            get_width(line2) + w <= console_width
                        ):
                            new_sb_lines.append(line1)
                            new_sb_lines.append(line2)
                            continue
                    if line.count(" == ") == 1 and line.endswith(":"):
                        whitespace = line_length2 - len(line.lstrip())
                        new_ws = line[0:whitespace] + "        "
                        line1 = line.split(" == ")[0] + " == ("
                        line2 = new_ws + line.split(" == ")[1][:-1] + "):"
                        if get_width(line1) + w <= console_width and (
                            get_width(line2) + w <= console_width
                        ):
                            new_sb_lines.append(line1)
                            new_sb_lines.append(line2)
                            continue
                    if (
                        line.count(" == ") == 1
                        and (line.count(":  #") == 1)
                        and (line.find(" == ") < line.find(":  #"))
                    ):
                        whitespace = line_length2 - len(line.lstrip())
                        new_ws = line[0:whitespace] + "        "
                        comments = "  #" + line.split(":  #")[1]
                        line0 = line.split(":  #")[0] + ":"
                        line1 = line0.split(" == ")[0] + " == ("
                        line2 = new_ws + line0.split(" == ")[1][:-1] + "):"
                        if get_width(line1) + w <= console_width and (
                            get_width(line2) + w <= console_width
                        ):
                            new_sb_lines.append(line1)
                            if (
                                get_width(line2 + comments) + w
                                <= console_width
                            ):
                                new_sb_lines.append(line2 + comments)
                            else:
                                new_sb_lines.append(line2)
                            continue
                    if line.count(" % ") == 1 and ("):") not in line:
                        whitespace = line_length2 - len(line.lstrip())
                        new_ws = line[0:whitespace] + "    "
                        line1 = line.split(" % ")[0] + " \\"
                        line2 = new_ws + "% " + line.split(" % ")[1]
                        if get_width(line1) + w <= console_width:
                            new_sb_lines.append(line1)
                            new_sb_lines.append(line2)
                            continue
                    if line.count(" = ") == 1 and ("  # ") not in line:
                        whitespace = line_length2 - len(line.lstrip())
                        new_ws = line[0:whitespace] + "    "
                        line1 = line.split(" = ")[0] + " = ("
                        line2 = new_ws + line.split(" = ")[1] + ")"
                        if get_width(line1) + w <= console_width and (
                            get_width(line2) + w <= console_width
                        ):
                            new_sb_lines.append(line1)
                            new_sb_lines.append(line2)
                            continue
                        elif get_width(line1) + w <= console_width:
                            if line2.count(" % ") == 1 and not (
                                line2.endswith(":")
                            ):
                                whitespace = line_length2 - len(
                                    line2.lstrip()
                                )
                                line2a = line2.split(" % ")[0] + " \\"
                                line2b = (
                                    new_ws + "% " + line2.split(" % ")[1]
                                )
                                if get_width(line2a) + w <= console_width:
                                    if (
                                        get_width(line2b) + w
                                        <= console_width
                                    ):
                                        new_sb_lines.append(line1)
                                        new_sb_lines.append(line2a)
                                        new_sb_lines.append(line2b)
                                        continue
                    if (
                        line.count(" = ") == 1
                        and (line.count("  # ") == 1)
                        and (line.find(" = ") < line.find("  # "))
                    ):
                        whitespace = line_length2 - len(line.lstrip())
                        new_ws = line[0:whitespace] + "        "
                        comments = "  # " + line.split("  # ")[1]
                        line0 = line.split("  # ")[0]
                        line1 = line0.split(" = ")[0] + " = ("
                        line2 = new_ws + line0.split(" = ")[1] + ")"
                        if get_width(line1) + w <= console_width and (
                            get_width(line2) + w <= console_width
                        ):
                            new_sb_lines.append(line1)
                            if (
                                get_width(line2 + comments) + w
                                <= console_width
                            ):
                                new_sb_lines.append(line2 + comments)
                            else:
                                new_sb_lines.append(line2)
                            continue
                new_sb_lines.append(line)

        if new_sb_lines:
            seleniumbase_lines = new_sb_lines
            python_code = "\n".join(seleniumbase_lines)

        extra_r_spaces = 2
        if console_width and (code_width + extra_r_spaces < console_width):
            used_width = code_width + extra_r_spaces

        magic_syntax = Syntax(
            python_code,
            "python",
            theme="monokai",
            line_numbers=line_numbers,
            code_width=used_width,
            word_wrap=word_wrap,
        )
        magic_console = Console()

        print("")
        print(save_line)
        print(" " + c1 + " ***  Here are the results:  >>> " + cr)
        # ----------------------------------------
        dash_length = 62  # May change
        if used_width and used_width + w < console_width:
            dash_length = used_width + w
        elif console_width:
            dash_length = console_width
        dashes = "-" * dash_length
        print(dashes)
        print_success = False
        if magic_syntax:
            try:
                magic_console.print(magic_syntax)
                print_success = True
            except Exception:
                pass
        if not magic_syntax or not print_success:
            for line in seleniumbase_lines:
                print(line)
        print(dashes)
        # ----------------------------------------

    new_file_name = None
    if copy:
        base_file_name = seleniumbase_file.split(".py")[0]
        new_locale = MD_F.get_locale_code(new_lang)
        new_ext = "_" + new_locale + ".py"
        for locale in MD_F.get_locale_list():
            ext = "_" + locale + ".py"
            if seleniumbase_file.endswith(ext):
                base_file_name = seleniumbase_file.split(ext)[0]
                break
        new_file_name = base_file_name + new_ext
    elif overwrite:
        new_file_name = seleniumbase_file
    else:
        pass  # Print-only run already done

    if not print_only:
        print("")
        print(save_line)
    else:
        pass  # Print-only run already done

    if new_file_name:
        out_file = open(new_file_name, mode="w+", encoding="utf-8")
        out_file.writelines("\r\n".join(seleniumbase_lines))
        out_file.close()
        results_saved = (
            "The translation was saved to: [[[%s]]]\n" "" % new_file_name
        )
        results_saved = results_saved.replace("[[[", "" + c1)
        results_saved = results_saved.replace("]]]", cr + "")
        print(results_saved)


if __name__ == "__main__":
    invalid_run_command()
