#!/usr/bin/env python3
# devel.a0fs.ru -- TOOLS:SEC:aw_pw_tool -- v0.r202505.1
# devel.a0fs.ru -- TOOLS:SEC:safe_pw -- v0.r202409.2
# devel.a0fs.ru -- pwtrns.py -- v0.r202402.8

from sys import stdin, stdout, stderr
from random import seed as rnd_seed, choice as rnd_choice
from argparse import ArgumentParser
from string import ascii_letters, digits
from typing import List, Iterable, Optional


### VAR
SAFECH= {
    'def': '%-=_;:+/,.@',
    'url': '-._',
}

TRDICT = {
    'f': 'а', ',': 'б', 'd': 'в', 'u': 'г', 'l': 'д', 't': 'е', '`': 'ё',
    ';': 'ж', 'p': 'з', 'b': 'и', 'q': 'й', 'r': 'к', 'k': 'л', 'v': 'м',
    'y': 'н', 'j': 'о', 'g': 'п', 'h': 'р', 'c': 'с', 'n': 'т', 'e': 'у',
    'a': 'ф', '[': 'х', 'w': 'ц', 'x': 'ч', 'i': 'ш', 'o': 'щ', 'm': 'ь',
    's': 'ы', ']': 'ъ', "'": 'э', '.': 'ю', 'z': 'я', 'F': 'А', '<': 'Б',
    'D': 'В', 'U': 'Г', 'L': 'Д', 'T': 'Е', '~': 'Ё', ':': 'Ж', 'P': 'З',
    'B': 'И', 'Q': 'Й', 'R': 'К', 'K': 'Л', 'V': 'М', 'Y': 'Н', 'J': 'О',
    'G': 'П', 'H': 'Р', 'C': 'С', 'N': 'Т', 'E': 'У', 'A': 'Ф', '{': 'Х',
    'W': 'Ц', 'X': 'Ч', 'I': 'Ш', 'O': 'Щ', 'M': 'Ь', 'S': 'Ы', '}': 'Ъ',
    '"': 'Э', '>': 'Ю', 'Z': 'Я',
}

GOODPWCH=ascii_letters + digits + ' '


### FUNC
def err(msg: str):
    for l in msg.splitlines():
        stderr.write(f'ERR: {l}\n')


def out(s: str):
    stdout.write(f'{s}\n')


def panic(code, msg):
    err(msg)
    exit(code)


def ptr_reverse(d: dict) -> dict:
    return dict([(v, k) for k, v in d.items()])


def get_args(words: Optional[List[str]]) -> Iterable[str]:
    if words and isinstance(words, (tuple, list)):
        for i in words:
            yield i.strip()
    
    else:
        for i in stdin:
            yield i.strip()

def out_res(flag: bool, word: str, tr_word: str):
    if flag:
        out(f'"{word}" -> "{tr_word}"')
    
    else:
        out(f'{tr_word}')


# ARGS
ap = ArgumentParser(
    prog='aw_pw_tool', 
    description='Инструмент для работы с паролями, их преобразованием и трансляцией'
)

ap.add_argument('-u', '--url', action='store_true', default=False,
                help='Режим фильтрации пароля от опасных для url символов'
                )

ap.add_argument('-S', '--show-passwd', action='store_true', default=False,
                help='Показывать пароли до преобразования'
                )

ap.add_argument('-t', '--pwtrans', action='store_true', default=False,
                help='Режим трансляции паролей из английской в русскую раскладку')

ap.add_argument('-r', '--reverse', action='store_true', default=False, 
                help='Для трансляции паролей: переводим из русской в английскую раскладку')


ap.add_argument('word', nargs='*', help='Слово для перевода')


### DO
try:
    args = ap.parse_args()

    if args.pwtrans:
        if args.reverse:
            d = ptr_reverse(TRDICT)

        else:
            d = TRDICT

        for w in get_args(args.word):
            out_res(
                args.show_passwd, 
                w, 
                ''.join(map(lambda x: d[x] if x in d else x, w))
            )

    else:
        # Init random generator
        rnd_seed()

        if args.url:
            cur_safe_ch = SAFECH['url']
        
        else:
            cur_safe_ch = SAFECH['def']

        GOODPWCH += cur_safe_ch

        for w in get_args(args.word):
            if len(w) == 0:
                break
                
            buf = ''
            for c in w:
                if c not in GOODPWCH:
                    c = rnd_choice(cur_safe_ch)
            
                buf += c

            out_res(
                args.show_passwd,
                w,
                buf
            )

except Exception as e:
    err(f'{type(e).__name__}: {e}')
    
except KeyboardInterrupt:
    exit()
