#!/usr/bin/env yacl

# Ansible style plays
from yacl_base import *
import yacl_execute


def yum_install(package_names, state="present", desc: str = ""):
    return {"name": desc, "yum": {"name": " ".join(package_names), "state": state}}


def service(name, state="start", desc: str = ""):
    return {"name": desc, "service": {"name": name, "state": state}}


class AnsiblePlay(YaclBaseClass, ABC):
    hosts = required
    tasks = required
    _execute = yacl_execute.yaml_serializer()


def AnsiblePlayWithName(name_: str):
    assert isinstance(name_, str)
    assert len(name_) > 0

    class AnsiblePlay(YaclBaseClass):
        hosts = required
        tasks = required
        _execute = yacl_execute.yaml_serializer()
        name = name_

    return AnsiblePlay


class WebServerPlay(AnsiblePlayWithName("Setup Apache servers")):
    hosts = ["webserver"]
    tasks = [
        yum_install(package_names=["apache"], desc="Install Apache webserver"),
        service(name="apache", state="start", desc="Start Apache"),
    ]


class MySQLPlay(AnsiblePlayWithName("Setup MySQL servers")):
    hosts = ["databaseserver"]
    tasks = [
        yum_install(package_names=["MySQL"], desc="Install MySQL server"),
    ]


class AnsiblePlays(YaclBaseClass, ABC):
    all_plays = required

    def _execute(result):
        serializer = yacl_execute.yaml_serializer()
        for play in result['all_plays']:
            serializer(play)


class AllMyPlays(AnsiblePlays):
    all_plays = [include(WebServerPlay), include(MySQLPlay)]


context = [{}]  # dummy one-element context

import yacl_eval

yacl_eval.go(AllMyPlays, context_set=context)
