#!/usr/bin/env yacl

from yacl_base import *
import yacl_context
import yacl_eval


class FileCommon(YaclBaseClass, ABC):
    create_parent_dirs = True

    machine = external_primary()

    path = external_primary()  # string or list of strings, will be joined by path separator.

    mode = 0o644

    def parent_dirs_modes():
        dir_modes = 0
        # add 'x' bit for ugo, if there is r or w (or x) mode for ugo.
        mode = get('mode')
        if mode | 0o700 != 0:  # u
            mode |= 0o100
        if mode | 0o070 != 0:  # g
            mode |= 0o010
        if mode | 0o007 != 0:  # o
            mode |= 0o001
        return dir_modes

    setuid = False
    setgid = False
    sticky = False

    def full_mode():
        mode = get('mode')
        if get('setuid'):
            mode |= 0o4000
        if get('setgid'):
            mode |= 0o2000
        if get('sticky'):
            mode |= 0o1000
        return mode

    uid = 0
    gid = 0
    user = None
    group = None

    acls = None  # or list

    # other_readable = True  # add 0o004 for the file by default.

    def _execute(result):
        print(f"file_op {result['machine']}:{result['path']} mode {result['full_mode']:o}")


class Dir(FileCommon, ABC):
    existing_ok = True
    clean = False


class FileOp(FileCommon, ABC):
    content = None  # optional, string or list of strings (will be joined by new line).


class SecureFileOp(FileOp):
    mode = 0o400


class EtcSudoersCustom(SecureFileOp):
    path = '/etc/sudoers.d/9myrules'

    def users_to_allow():
        return get_from_context()  # default_value=None) or ['user']

    def content():
        return "\n".join(f'{username} ALL=(ALL) NOPASSWD: ALL' for username in get('users_to_allow'))


context_set = [yacl_context.Cross(
    {'machine': ['alpha', 'beta']},
    [{'users_to_allow': ['alice', 'bob']}])]

# Make this work maybe.
context_set.extend([yacl_context.Cross(
    {'machine': ['zeta']},
    [{'users_to_allow': ['charlie']}])
])

results = yacl_eval.go(EtcSudoersCustom, context_set=context_set)
