#!/usr/bin/env python
"""Creates a parent/child relationship between two already existing resources.
The Eve docs call this "sub resources"
(https://docs.python-eve.org/en/stable/features.html#sub-resources)

Usage:
    mkrel [-h|--help] [-p|--as_parent_ref] parent child
      NOTE: Must be run in the project folder
            The name of parent or child can entered as either singular or plural

Examples:
    mkrel employer employee
    mkrel groups members --as_parent_ref

License:
    MIT License

    Copyright (c) 2021 Michael Ottoson

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    SOFTWARE.
"""

import os
import argparse
import itertools
from libcst import *
from singplu import get_pair

def get_comma():
    return Comma(
        whitespace_before=SimpleWhitespace(
            value='',
        ),
        whitespace_after=ParenthesizedWhitespace(
            first_line=TrailingWhitespace(
                whitespace=SimpleWhitespace(
                    value='',
                ),
                comment=None,
                newline=Newline(
                    value=None,
                ),
            ),
            empty_lines=[],
            indent=True,
            last_line=SimpleWhitespace(
                value='    ',
            ),
        ),
    )


class ChildLinksInserter(CSTTransformer):
    def __init__(self, parent, child, parents, children, parent_ref):
        self.parent = parent
        self.child = child
        self.parents = parents
        self.children = children
        self.parent_ref = parent_ref

    def leave_FunctionDef(self, original_node, updated_node):
        if (not original_node.name.value == f'_add_links_to_{self.child}') and (not original_node.name.value == 'add_hooks'):
            return original_node

        new_body = []
        for item in original_node.body.body:
            new_body.append(item)

        if original_node.name.value == f'_add_links_to_{self.child}':
            new_body.append(self.make_parent_link())
        if original_node.name.value == 'add_hooks':
            new_body.extend(self.add_rel_hooks())

        return updated_node.with_changes(
            body=updated_node.body.with_changes(
                body=new_body
            )
        )

    def make_parent_link(self):
        return If(
            test=Call(
                func=Attribute(
                    value=Name(
                        value=f'{self.child}',
                        lpar=[],
                        rpar=[],
                    ),
                    attr=Name(
                        value='get',
                        lpar=[],
                        rpar=[],
                    ),
                    dot=Dot(
                        whitespace_before=SimpleWhitespace(
                            value='',
                        ),
                        whitespace_after=SimpleWhitespace(
                            value='',
                        ),
                    ),
                    lpar=[],
                    rpar=[],
                ),
                args=[
                    Arg(
                        value=SimpleString(
                            value=f"'{self.parent_ref}'",
                            lpar=[],
                            rpar=[],
                        ),
                        keyword=None,
                        equal=MaybeSentinel.DEFAULT,
                        comma=MaybeSentinel.DEFAULT,
                        star='',
                        whitespace_after_star=SimpleWhitespace(
                            value='',
                        ),
                        whitespace_after_arg=SimpleWhitespace(
                            value='',
                        ),
                    ),
                ],
                lpar=[],
                rpar=[],
                whitespace_after_func=SimpleWhitespace(
                    value='',
                ),
                whitespace_before_args=SimpleWhitespace(
                    value='',
                ),
            ),
            body=IndentedBlock(
                body=[
                    SimpleStatementLine(
                        body=[
                            Assign(
                                targets=[
                                    AssignTarget(
                                        target=Subscript(
                                            value=Subscript(
                                                value=Name(
                                                    value=f'{self.child}',
                                                    lpar=[],
                                                    rpar=[],
                                                ),
                                                slice=[
                                                    SubscriptElement(
                                                        slice=Index(
                                                            value=SimpleString(
                                                                value="'_links'",
                                                                lpar=[],
                                                                rpar=[],
                                                            ),
                                                        ),
                                                        comma=MaybeSentinel.DEFAULT,
                                                    ),
                                                ],
                                                lbracket=LeftSquareBracket(
                                                    whitespace_after=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                ),
                                                rbracket=RightSquareBracket(
                                                    whitespace_before=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                ),
                                                lpar=[],
                                                rpar=[],
                                                whitespace_after_value=SimpleWhitespace(
                                                    value='',
                                                ),
                                            ),
                                            slice=[
                                                SubscriptElement(
                                                    slice=Index(
                                                        value=SimpleString(
                                                            value="'parent'",
                                                            lpar=[],
                                                            rpar=[],
                                                        ),
                                                    ),
                                                    comma=MaybeSentinel.DEFAULT,
                                                ),
                                            ],
                                            lbracket=LeftSquareBracket(
                                                whitespace_after=SimpleWhitespace(
                                                    value='',
                                                ),
                                            ),
                                            rbracket=RightSquareBracket(
                                                whitespace_before=SimpleWhitespace(
                                                    value='',
                                                ),
                                            ),
                                            lpar=[],
                                            rpar=[],
                                            whitespace_after_value=SimpleWhitespace(
                                                value='',
                                            ),
                                        ),
                                        whitespace_before_equal=SimpleWhitespace(
                                            value=' ',
                                        ),
                                        whitespace_after_equal=SimpleWhitespace(
                                            value=' ',
                                        ),
                                    ),
                                ],
                                value=Dict(
                                    elements=[
                                        DictElement(
                                            key=SimpleString(
                                                value="'href'",
                                                lpar=[],
                                                rpar=[],
                                            ),
                                            value=FormattedString(  # ding (make_parent_link, 1)
                                                parts=[
                                                    FormattedStringText(
                                                        value=f'/{self.parents}/',
                                                    ),
                                                    FormattedStringExpression(
                                                        expression=Subscript(
                                                            value=Name(
                                                                value=f'{self.child}',
                                                                lpar=[],
                                                                rpar=[],
                                                            ),
                                                            slice=[
                                                                SubscriptElement(
                                                                    slice=Index(
                                                                        value=SimpleString(
                                                                            value=f'"{self.parent_ref}"',
                                                                            lpar=[],
                                                                            rpar=[],
                                                                        ),
                                                                    ),
                                                                    comma=MaybeSentinel.DEFAULT,
                                                                ),
                                                            ],
                                                            lbracket=LeftSquareBracket(
                                                                whitespace_after=SimpleWhitespace(
                                                                    value='',
                                                                ),
                                                            ),
                                                            rbracket=RightSquareBracket(
                                                                whitespace_before=SimpleWhitespace(
                                                                    value='',
                                                                ),
                                                            ),
                                                            lpar=[],
                                                            rpar=[],
                                                            whitespace_after_value=SimpleWhitespace(
                                                                value='',
                                                            ),
                                                        ),
                                                        conversion=None,
                                                        format_spec=None,
                                                        whitespace_before_expression=SimpleWhitespace(
                                                            value='',
                                                        ),
                                                        whitespace_after_expression=SimpleWhitespace(
                                                            value='',
                                                        ),
                                                        equal=None,
                                                    ),
                                                ],
                                                start="f'",
                                                end="'",
                                                lpar=[],
                                                rpar=[],
                                            ),
                                            comma=Comma(
                                                whitespace_before=SimpleWhitespace(
                                                    value='',
                                                ),
                                                whitespace_after=ParenthesizedWhitespace(
                                                    first_line=TrailingWhitespace(
                                                        whitespace=SimpleWhitespace(
                                                            value='',
                                                        ),
                                                        comment=None,
                                                        newline=Newline(
                                                            value=None,
                                                        ),
                                                    ),
                                                    empty_lines=[],
                                                    indent=True,
                                                    last_line=SimpleWhitespace(
                                                        value='    ',
                                                    ),
                                                ),
                                            ),
                                            whitespace_before_colon=SimpleWhitespace(
                                                value='',
                                            ),
                                            whitespace_after_colon=SimpleWhitespace(
                                                value=' ',
                                            ),
                                        ),
                                        DictElement(
                                            key=SimpleString(
                                                value="'title'",
                                                lpar=[],
                                                rpar=[],
                                            ),
                                            value=SimpleString(
                                                value=f"'{self.parents}'",
                                                lpar=[],
                                                rpar=[],
                                            ),
                                            comma=MaybeSentinel.DEFAULT,
                                            whitespace_before_colon=SimpleWhitespace(
                                                value='',
                                            ),
                                            whitespace_after_colon=SimpleWhitespace(
                                                value=' ',
                                            ),
                                        ),
                                    ],
                                    lbrace=LeftCurlyBrace(
                                        whitespace_after=ParenthesizedWhitespace(
                                            first_line=TrailingWhitespace(
                                                whitespace=SimpleWhitespace(
                                                    value='',
                                                ),
                                                comment=None,
                                                newline=Newline(
                                                    value=None,
                                                ),
                                            ),
                                            empty_lines=[],
                                            indent=True,
                                            last_line=SimpleWhitespace(
                                                value='    ',
                                            ),
                                        ),
                                    ),
                                    rbrace=RightCurlyBrace(
                                        whitespace_before=ParenthesizedWhitespace(
                                            first_line=TrailingWhitespace(
                                                whitespace=SimpleWhitespace(
                                                    value='',
                                                ),
                                                comment=None,
                                                newline=Newline(
                                                    value=None,
                                                ),
                                            ),
                                            empty_lines=[],
                                            indent=True,
                                            last_line=SimpleWhitespace(
                                                value='',
                                            ),
                                        ),
                                    ),
                                    lpar=[],
                                    rpar=[],
                                ),
                                semicolon=MaybeSentinel.DEFAULT,
                            ),
                        ],
                        leading_lines=[],
                        trailing_whitespace=TrailingWhitespace(
                            whitespace=SimpleWhitespace(
                                value='',
                            ),
                            comment=None,
                            newline=Newline(
                                value=None,
                            ),
                        ),
                    ),
                    SimpleStatementLine(
                        body=[
                            Assign(
                                targets=[
                                    AssignTarget(
                                        target=Subscript(
                                            value=Subscript(
                                                value=Name(
                                                    value=f'{self.child}',
                                                    lpar=[],
                                                    rpar=[],
                                                ),
                                                slice=[
                                                    SubscriptElement(
                                                        slice=Index(
                                                            value=SimpleString(
                                                                value="'_links'",
                                                                lpar=[],
                                                                rpar=[],
                                                            ),
                                                        ),
                                                        comma=MaybeSentinel.DEFAULT,
                                                    ),
                                                ],
                                                lbracket=LeftSquareBracket(
                                                    whitespace_after=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                ),
                                                rbracket=RightSquareBracket(
                                                    whitespace_before=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                ),
                                                lpar=[],
                                                rpar=[],
                                                whitespace_after_value=SimpleWhitespace(
                                                    value='',
                                                ),
                                            ),
                                            slice=[
                                                SubscriptElement(
                                                    slice=Index(
                                                        value=SimpleString(
                                                            value="'collection'",
                                                            lpar=[],
                                                            rpar=[],
                                                        ),
                                                    ),
                                                    comma=MaybeSentinel.DEFAULT,
                                                ),
                                            ],
                                            lbracket=LeftSquareBracket(
                                                whitespace_after=SimpleWhitespace(
                                                    value='',
                                                ),
                                            ),
                                            rbracket=RightSquareBracket(
                                                whitespace_before=SimpleWhitespace(
                                                    value='',
                                                ),
                                            ),
                                            lpar=[],
                                            rpar=[],
                                            whitespace_after_value=SimpleWhitespace(
                                                value='',
                                            ),
                                        ),
                                        whitespace_before_equal=SimpleWhitespace(
                                            value=' ',
                                        ),
                                        whitespace_after_equal=SimpleWhitespace(
                                            value=' ',
                                        ),
                                    ),
                                ],
                                value=Dict(
                                    elements=[
                                        DictElement(
                                            key=SimpleString(
                                                value="'href'",
                                                lpar=[],
                                                rpar=[],
                                            ),
                                            value=FormattedString(  # ding (make_parent_link, 2)
                                                parts=[
                                                    FormattedStringText(
                                                        value=f'/{self.parents}/',
                                                    ),
                                                    FormattedStringExpression(
                                                        expression=Subscript(
                                                            value=Name(
                                                                value=f'{self.child}',
                                                                lpar=[],
                                                                rpar=[],
                                                            ),
                                                            slice=[
                                                                SubscriptElement(
                                                                    slice=Index(
                                                                        value=SimpleString(
                                                                            value=f'"{self.parent_ref}"',
                                                                            lpar=[],
                                                                            rpar=[],
                                                                        ),
                                                                    ),
                                                                    comma=MaybeSentinel.DEFAULT,
                                                                ),
                                                            ],
                                                            lbracket=LeftSquareBracket(
                                                                whitespace_after=SimpleWhitespace(
                                                                    value='',
                                                                ),
                                                            ),
                                                            rbracket=RightSquareBracket(
                                                                whitespace_before=SimpleWhitespace(
                                                                    value='',
                                                                ),
                                                            ),
                                                            lpar=[],
                                                            rpar=[],
                                                            whitespace_after_value=SimpleWhitespace(
                                                                value='',
                                                            ),
                                                        ),
                                                        conversion=None,
                                                        format_spec=None,
                                                        whitespace_before_expression=SimpleWhitespace(
                                                            value='',
                                                        ),
                                                        whitespace_after_expression=SimpleWhitespace(
                                                            value='',
                                                        ),
                                                        equal=None,
                                                    ),
                                                    FormattedStringText(
                                                        value=f'/{self.children}',
                                                    ),
                                                ],
                                                start="f'",
                                                end="'",
                                                lpar=[],
                                                rpar=[],
                                            ),
                                            comma=Comma(
                                                whitespace_before=SimpleWhitespace(
                                                    value='',
                                                ),
                                                whitespace_after=ParenthesizedWhitespace(
                                                    first_line=TrailingWhitespace(
                                                        whitespace=SimpleWhitespace(
                                                            value='',
                                                        ),
                                                        comment=None,
                                                        newline=Newline(
                                                            value=None,
                                                        ),
                                                    ),
                                                    empty_lines=[],
                                                    indent=True,
                                                    last_line=SimpleWhitespace(
                                                        value='    ',
                                                    ),
                                                ),
                                            ),
                                            whitespace_before_colon=SimpleWhitespace(
                                                value='',
                                            ),
                                            whitespace_after_colon=SimpleWhitespace(
                                                value=' ',
                                            ),
                                        ),
                                        DictElement(
                                            key=SimpleString(
                                                value="'title'",
                                                lpar=[],
                                                rpar=[],
                                            ),
                                            value=SimpleString(
                                                value=f"'{self.parent}_{self.children}'",
                                                lpar=[],
                                                rpar=[],
                                            ),
                                            comma=MaybeSentinel.DEFAULT,
                                            whitespace_before_colon=SimpleWhitespace(
                                                value='',
                                            ),
                                            whitespace_after_colon=SimpleWhitespace(
                                                value=' ',
                                            ),
                                        ),
                                    ],
                                    lbrace=LeftCurlyBrace(
                                        whitespace_after=ParenthesizedWhitespace(
                                            first_line=TrailingWhitespace(
                                                whitespace=SimpleWhitespace(
                                                    value='',
                                                ),
                                                comment=None,
                                                newline=Newline(
                                                    value=None,
                                                ),
                                            ),
                                            empty_lines=[],
                                            indent=True,
                                            last_line=SimpleWhitespace(
                                                value='    ',
                                            ),
                                        ),
                                    ),
                                    rbrace=RightCurlyBrace(
                                        whitespace_before=ParenthesizedWhitespace(
                                            first_line=TrailingWhitespace(
                                                whitespace=SimpleWhitespace(
                                                    value='',
                                                ),
                                                comment=None,
                                                newline=Newline(
                                                    value=None,
                                                ),
                                            ),
                                            empty_lines=[],
                                            indent=True,
                                            last_line=SimpleWhitespace(
                                                value='',
                                            ),
                                        ),
                                    ),
                                    lpar=[],
                                    rpar=[],
                                ),
                                semicolon=MaybeSentinel.DEFAULT,
                            ),
                        ],
                        leading_lines=[],
                        trailing_whitespace=TrailingWhitespace(
                            whitespace=SimpleWhitespace(
                                value='',
                            ),
                            comment=None,
                            newline=Newline(
                                value=None,
                            ),
                        ),
                    ),
                ],
                header=TrailingWhitespace(
                    whitespace=SimpleWhitespace(
                        value='',
                    ),
                    comment=None,
                    newline=Newline(
                        value=None,
                    ),
                ),
                indent=None,
                footer=[],
            ),
            orelse=Else(
                body=IndentedBlock(
                    body=[
                        SimpleStatementLine(
                            body=[
                                Assign(
                                    targets=[
                                        AssignTarget(
                                            target=Subscript(
                                                value=Subscript(
                                                    value=Name(
                                                        value=f'{self.child}',
                                                        lpar=[],
                                                        rpar=[],
                                                    ),
                                                    slice=[
                                                        SubscriptElement(
                                                            slice=Index(
                                                                value=SimpleString(
                                                                    value="'_links'",
                                                                    lpar=[],
                                                                    rpar=[],
                                                                ),
                                                            ),
                                                            comma=MaybeSentinel.DEFAULT,
                                                        ),
                                                    ],
                                                    lbracket=LeftSquareBracket(
                                                        whitespace_after=SimpleWhitespace(
                                                            value='',
                                                        ),
                                                    ),
                                                    rbracket=RightSquareBracket(
                                                        whitespace_before=SimpleWhitespace(
                                                            value='',
                                                        ),
                                                    ),
                                                    lpar=[],
                                                    rpar=[],
                                                    whitespace_after_value=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                ),
                                                slice=[
                                                    SubscriptElement(
                                                        slice=Index(
                                                            value=SimpleString(
                                                                value="'parent'",
                                                                lpar=[],
                                                                rpar=[],
                                                            ),
                                                        ),
                                                        comma=MaybeSentinel.DEFAULT,
                                                    ),
                                                ],
                                                lbracket=LeftSquareBracket(
                                                    whitespace_after=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                ),
                                                rbracket=RightSquareBracket(
                                                    whitespace_before=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                ),
                                                lpar=[],
                                                rpar=[],
                                                whitespace_after_value=SimpleWhitespace(
                                                    value='',
                                                ),
                                            ),
                                            whitespace_before_equal=SimpleWhitespace(
                                                value=' ',
                                            ),
                                            whitespace_after_equal=SimpleWhitespace(
                                                value=' ',
                                            ),
                                        ),
                                    ],
                                    value=Dict(
                                        elements=[
                                            DictElement(
                                                key=SimpleString(
                                                    value="'href'",
                                                    lpar=[],
                                                    rpar=[],
                                                ),
                                                value=SimpleString(
                                                    value="'/'",
                                                    lpar=[],
                                                    rpar=[],
                                                ),
                                                comma=Comma(
                                                    whitespace_before=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                    whitespace_after=ParenthesizedWhitespace(
                                                        first_line=TrailingWhitespace(
                                                            whitespace=SimpleWhitespace(
                                                                value='',
                                                            ),
                                                            comment=None,
                                                            newline=Newline(
                                                                value=None,
                                                            ),
                                                        ),
                                                        empty_lines=[],
                                                        indent=True,
                                                        last_line=SimpleWhitespace(
                                                            value='    ',
                                                        ),
                                                    ),
                                                ),
                                                whitespace_before_colon=SimpleWhitespace(
                                                    value='',
                                                ),
                                                whitespace_after_colon=SimpleWhitespace(
                                                    value=' ',
                                                ),
                                            ),
                                            DictElement(
                                                key=SimpleString(
                                                    value="'title'",
                                                    lpar=[],
                                                    rpar=[],
                                                ),
                                                value=SimpleString(
                                                    value="'home'",
                                                    lpar=[],
                                                    rpar=[],
                                                ),
                                                comma=MaybeSentinel.DEFAULT,
                                                whitespace_before_colon=SimpleWhitespace(
                                                    value='',
                                                ),
                                                whitespace_after_colon=SimpleWhitespace(
                                                    value=' ',
                                                ),
                                            ),
                                        ],
                                        lbrace=LeftCurlyBrace(
                                            whitespace_after=ParenthesizedWhitespace(
                                                first_line=TrailingWhitespace(
                                                    whitespace=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                    comment=None,
                                                    newline=Newline(
                                                        value=None,
                                                    ),
                                                ),
                                                empty_lines=[],
                                                indent=True,
                                                last_line=SimpleWhitespace(
                                                    value='    ',
                                                ),
                                            ),
                                        ),
                                        rbrace=RightCurlyBrace(
                                            whitespace_before=ParenthesizedWhitespace(
                                                first_line=TrailingWhitespace(
                                                    whitespace=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                    comment=None,
                                                    newline=Newline(
                                                        value=None,
                                                    ),
                                                ),
                                                empty_lines=[],
                                                indent=True,
                                                last_line=SimpleWhitespace(
                                                    value='',
                                                ),
                                            ),
                                        ),
                                        lpar=[],
                                        rpar=[],
                                    ),
                                    semicolon=MaybeSentinel.DEFAULT,
                                ),
                            ],
                            leading_lines=[],
                            trailing_whitespace=TrailingWhitespace(
                                whitespace=SimpleWhitespace(
                                    value='',
                                ),
                                comment=None,
                                newline=Newline(
                                    value=None,
                                ),
                            ),
                        ),
                        SimpleStatementLine(
                            body=[
                                Assign(
                                    targets=[
                                        AssignTarget(
                                            target=Subscript(
                                                value=Subscript(
                                                    value=Name(
                                                        value=f'{self.child}',
                                                        lpar=[],
                                                        rpar=[],
                                                    ),
                                                    slice=[
                                                        SubscriptElement(
                                                            slice=Index(
                                                                value=SimpleString(
                                                                    value="'_links'",
                                                                    lpar=[],
                                                                    rpar=[],
                                                                ),
                                                            ),
                                                            comma=MaybeSentinel.DEFAULT,
                                                        ),
                                                    ],
                                                    lbracket=LeftSquareBracket(
                                                        whitespace_after=SimpleWhitespace(
                                                            value='',
                                                        ),
                                                    ),
                                                    rbracket=RightSquareBracket(
                                                        whitespace_before=SimpleWhitespace(
                                                            value='',
                                                        ),
                                                    ),
                                                    lpar=[],
                                                    rpar=[],
                                                    whitespace_after_value=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                ),
                                                slice=[
                                                    SubscriptElement(
                                                        slice=Index(
                                                            value=SimpleString(
                                                                value="'collection'",
                                                                lpar=[],
                                                                rpar=[],
                                                            ),
                                                        ),
                                                        comma=MaybeSentinel.DEFAULT,
                                                    ),
                                                ],
                                                lbracket=LeftSquareBracket(
                                                    whitespace_after=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                ),
                                                rbracket=RightSquareBracket(
                                                    whitespace_before=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                ),
                                                lpar=[],
                                                rpar=[],
                                                whitespace_after_value=SimpleWhitespace(
                                                    value='',
                                                ),
                                            ),
                                            whitespace_before_equal=SimpleWhitespace(
                                                value=' ',
                                            ),
                                            whitespace_after_equal=SimpleWhitespace(
                                                value=' ',
                                            ),
                                        ),
                                    ],
                                    value=Dict(
                                        elements=[
                                            DictElement(
                                                key=SimpleString(
                                                    value="'href'",
                                                    lpar=[],
                                                    rpar=[],
                                                ),
                                                value=SimpleString(
                                                    value=f"'/{self.children}'",
                                                    lpar=[],
                                                    rpar=[],
                                                ),
                                                comma=Comma(
                                                    whitespace_before=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                    whitespace_after=ParenthesizedWhitespace(
                                                        first_line=TrailingWhitespace(
                                                            whitespace=SimpleWhitespace(
                                                                value='',
                                                            ),
                                                            comment=None,
                                                            newline=Newline(
                                                                value=None,
                                                            ),
                                                        ),
                                                        empty_lines=[],
                                                        indent=True,
                                                        last_line=SimpleWhitespace(
                                                            value='    ',
                                                        ),
                                                    ),
                                                ),
                                                whitespace_before_colon=SimpleWhitespace(
                                                    value='',
                                                ),
                                                whitespace_after_colon=SimpleWhitespace(
                                                    value=' ',
                                                ),
                                            ),
                                            DictElement(
                                                key=SimpleString(
                                                    value="'title'",
                                                    lpar=[],
                                                    rpar=[],
                                                ),
                                                value=SimpleString(
                                                    value=f"'{self.children}'",
                                                    lpar=[],
                                                    rpar=[],
                                                ),
                                                comma=MaybeSentinel.DEFAULT,
                                                whitespace_before_colon=SimpleWhitespace(
                                                    value='',
                                                ),
                                                whitespace_after_colon=SimpleWhitespace(
                                                    value=' ',
                                                ),
                                            ),
                                        ],
                                        lbrace=LeftCurlyBrace(
                                            whitespace_after=ParenthesizedWhitespace(
                                                first_line=TrailingWhitespace(
                                                    whitespace=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                    comment=None,
                                                    newline=Newline(
                                                        value=None,
                                                    ),
                                                ),
                                                empty_lines=[],
                                                indent=True,
                                                last_line=SimpleWhitespace(
                                                    value='    ',
                                                ),
                                            ),
                                        ),
                                        rbrace=RightCurlyBrace(
                                            whitespace_before=ParenthesizedWhitespace(
                                                first_line=TrailingWhitespace(
                                                    whitespace=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                    comment=None,
                                                    newline=Newline(
                                                        value=None,
                                                    ),
                                                ),
                                                empty_lines=[],
                                                indent=True,
                                                last_line=SimpleWhitespace(
                                                    value='',
                                                ),
                                            ),
                                        ),
                                        lpar=[],
                                        rpar=[],
                                    ),
                                    semicolon=MaybeSentinel.DEFAULT,
                                ),
                            ],
                            leading_lines=[],
                            trailing_whitespace=TrailingWhitespace(
                                whitespace=SimpleWhitespace(
                                    value='',
                                ),
                                comment=None,
                                newline=Newline(
                                    value=None,
                                ),
                            ),
                        ),
                    ],
                    header=TrailingWhitespace(
                        whitespace=SimpleWhitespace(
                            value='',
                        ),
                        comment=None,
                        newline=Newline(
                            value=None,
                        ),
                    ),
                    indent=None,
                    footer=[],
                ),
                leading_lines=[],
                whitespace_before_colon=SimpleWhitespace(
                    value='',
                ),
            ),
            leading_lines=[],
            whitespace_before_test=SimpleWhitespace(
                value=' ',
            ),
            whitespace_after_test=SimpleWhitespace(
                value='',
            ),
        )

    def add_rel_hooks(self):
        return [
            SimpleStatementLine(
                body=[
                    AugAssign(
                        target=Attribute(
                            value=Name(
                                value='app',
                                lpar=[],
                                rpar=[],
                            ),
                            attr=Name(
                                value=f'on_fetched_item_{self.parents}_{self.children}',
                                lpar=[],
                                rpar=[],
                            ),
                            dot=Dot(
                                whitespace_before=SimpleWhitespace(
                                    value='',
                                ),
                                whitespace_after=SimpleWhitespace(
                                    value='',
                                ),
                            ),
                            lpar=[],
                            rpar=[],
                        ),
                        operator=AddAssign(
                            whitespace_before=SimpleWhitespace(
                                value=' ',
                            ),
                            whitespace_after=SimpleWhitespace(
                                value=' ',
                            ),
                        ),
                        value=Name(
                            value=f'_add_links_to_{self.child}',
                            lpar=[],
                            rpar=[],
                        ),
                        semicolon=MaybeSentinel.DEFAULT,
                    ),
                ],
                leading_lines=[
                    EmptyLine(
                        indent=False,
                        whitespace=SimpleWhitespace(
                            value='',
                        ),
                        comment=None,
                        newline=Newline(
                            value=None,
                        ),
                    ),
                ],
                trailing_whitespace=TrailingWhitespace(
                    whitespace=SimpleWhitespace(
                        value='',
                    ),
                    comment=None,
                    newline=Newline(
                        value=None,
                    ),
                ),
            ),
            SimpleStatementLine(
                body=[
                    AugAssign(
                        target=Attribute(
                            value=Name(
                                value='app',
                                lpar=[],
                                rpar=[],
                            ),
                            attr=Name(
                                value=f'on_fetched_resource_{self.parents}_{self.children}',
                                lpar=[],
                                rpar=[],
                            ),
                            dot=Dot(
                                whitespace_before=SimpleWhitespace(
                                    value='',
                                ),
                                whitespace_after=SimpleWhitespace(
                                    value='',
                                ),
                            ),
                            lpar=[],
                            rpar=[],
                        ),
                        operator=AddAssign(
                            whitespace_before=SimpleWhitespace(
                                value=' ',
                            ),
                            whitespace_after=SimpleWhitespace(
                                value=' ',
                            ),
                        ),
                        value=Name(
                            value=f'_add_links_to_{self.children}_collection',
                            lpar=[],
                            rpar=[],
                        ),
                        semicolon=MaybeSentinel.DEFAULT,
                    ),
                ],
                leading_lines=[],
                trailing_whitespace=TrailingWhitespace(
                    whitespace=SimpleWhitespace(
                        value='',
                    ),
                    comment=None,
                    newline=Newline(
                        value=None,
                    ),
                ),
            ),
            SimpleStatementLine(
                body=[
                    AugAssign(
                        target=Attribute(
                            value=Name(
                                value='app',
                                lpar=[],
                                rpar=[],
                            ),
                            attr=Name(
                                value=f'on_post_POST_{self.parents}_{self.children}',
                                lpar=[],
                                rpar=[],
                            ),
                            dot=Dot(
                                whitespace_before=SimpleWhitespace(
                                    value='',
                                ),
                                whitespace_after=SimpleWhitespace(
                                    value='',
                                ),
                            ),
                            lpar=[],
                            rpar=[],
                        ),
                        operator=AddAssign(
                            whitespace_before=SimpleWhitespace(
                                value=' ',
                            ),
                            whitespace_after=SimpleWhitespace(
                                value=' ',
                            ),
                        ),
                        value=Name(
                            value=f'_post_{self.children}',
                            lpar=[],
                            rpar=[],
                        ),
                        semicolon=MaybeSentinel.DEFAULT,
                    ),
                ],
                leading_lines=[],
                trailing_whitespace=TrailingWhitespace(
                    whitespace=SimpleWhitespace(
                        value='',
                    ),
                    comment=None,
                    newline=Newline(
                        value=None,
                    ),
                ),
            )
        ]






class ParentLinksInserter(CSTTransformer):
    def __init__(self, parent, child, parents, children, parent_ref):
        self.parent = parent
        self.child = child
        self.parents = parents
        self.children = children
        self.parent_ref = parent_ref

    def leave_FunctionDef(self, original_node, updated_node):
        if not original_node.name.value == f'_add_links_to_{self.parent}':
            return original_node

        new_body = []
        for item in original_node.body.body:
            new_body.append(item)
        new_body.append(self.make_children_link())

        return updated_node.with_changes(
            body=updated_node.body.with_changes(
                body=new_body
            )
        )

    def make_children_link(self):
        return SimpleStatementLine(
            body=[
                Assign(
                    targets=[
                        AssignTarget(
                            target=Subscript(
                                value=Subscript(
                                    value=Name(
                                        value=f'{self.parent}',
                                        lpar=[],
                                        rpar=[],
                                    ),
                                    slice=[
                                        SubscriptElement(
                                            slice=Index(
                                                value=SimpleString(
                                                    value="'_links'",
                                                    lpar=[],
                                                    rpar=[],
                                                ),
                                            ),
                                            comma=MaybeSentinel.DEFAULT,
                                        ),
                                    ],
                                    lbracket=LeftSquareBracket(
                                        whitespace_after=SimpleWhitespace(
                                            value='',
                                        ),
                                    ),
                                    rbracket=RightSquareBracket(
                                        whitespace_before=SimpleWhitespace(
                                            value='',
                                        ),
                                    ),
                                    lpar=[],
                                    rpar=[],
                                    whitespace_after_value=SimpleWhitespace(
                                        value='',
                                    ),
                                ),
                                slice=[
                                    SubscriptElement(
                                        slice=Index(
                                            value=SimpleString(
                                                value=f"'{self.children}'",
                                                lpar=[],
                                                rpar=[],
                                            ),
                                        ),
                                        comma=MaybeSentinel.DEFAULT,
                                    ),
                                ],
                                lbracket=LeftSquareBracket(
                                    whitespace_after=SimpleWhitespace(
                                        value='',
                                    ),
                                ),
                                rbracket=RightSquareBracket(
                                    whitespace_before=SimpleWhitespace(
                                        value='',
                                    ),
                                ),
                                lpar=[],
                                rpar=[],
                                whitespace_after_value=SimpleWhitespace(
                                    value='',
                                ),
                            ),
                            whitespace_before_equal=SimpleWhitespace(
                                value=' ',
                            ),
                            whitespace_after_equal=SimpleWhitespace(
                                value=' ',
                            ),
                        ),
                    ],
                    value=Dict(
                        elements=[
                            DictElement(
                                key=SimpleString(
                                    value="'href'",
                                    lpar=[],
                                    rpar=[],
                                ),
                                value=FormattedString(  # ding (make_children_link)
                                    parts=[
                                        FormattedStringText(
                                            value=f'/{self.parents}/',
                                        ),
                                        FormattedStringExpression(
                                            expression=Subscript(
                                                value=Name(
                                                    value=f'{self.parent}',
                                                    lpar=[],
                                                    rpar=[],
                                                ),
                                                slice=[
                                                    SubscriptElement(
                                                        slice=Index(
                                                            value=SimpleString(
                                                                value='"_id"',  ####### ding
                                                                lpar=[],
                                                                rpar=[],
                                                            ),
                                                        ),
                                                        comma=MaybeSentinel.DEFAULT,
                                                    ),
                                                ],
                                                lbracket=LeftSquareBracket(
                                                    whitespace_after=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                ),
                                                rbracket=RightSquareBracket(
                                                    whitespace_before=SimpleWhitespace(
                                                        value='',
                                                    ),
                                                ),
                                                lpar=[],
                                                rpar=[],
                                                whitespace_after_value=SimpleWhitespace(
                                                    value='',
                                                ),
                                            ),
                                            conversion=None,
                                            format_spec=None,
                                            whitespace_before_expression=SimpleWhitespace(
                                                value='',
                                            ),
                                            whitespace_after_expression=SimpleWhitespace(
                                                value='',
                                            ),
                                            equal=None,
                                        ),
                                        FormattedStringText(
                                            value=f'/{self.children}',
                                        ),
                                    ],
                                    start="f'",
                                    end="'",
                                    lpar=[],
                                    rpar=[],
                                ),
                                comma=Comma(
                                    whitespace_before=SimpleWhitespace(
                                        value='',
                                    ),
                                    whitespace_after=ParenthesizedWhitespace(
                                        first_line=TrailingWhitespace(
                                            whitespace=SimpleWhitespace(
                                                value='',
                                            ),
                                            comment=None,
                                            newline=Newline(
                                                value=None,
                                            ),
                                        ),
                                        empty_lines=[],
                                        indent=True,
                                        last_line=SimpleWhitespace(
                                            value='    ',
                                        ),
                                    ),
                                ),
                                whitespace_before_colon=SimpleWhitespace(
                                    value='',
                                ),
                                whitespace_after_colon=SimpleWhitespace(
                                    value=' ',
                                ),
                            ),
                            DictElement(
                                key=SimpleString(
                                    value="'title'",
                                    lpar=[],
                                    rpar=[],
                                ),
                                value=SimpleString(
                                    value=f"'{self.children}'",
                                    lpar=[],
                                    rpar=[],
                                ),
                                comma=MaybeSentinel.DEFAULT,
                                whitespace_before_colon=SimpleWhitespace(
                                    value='',
                                ),
                                whitespace_after_colon=SimpleWhitespace(
                                    value=' ',
                                ),
                            ),
                        ],
                        lbrace=LeftCurlyBrace(
                            whitespace_after=ParenthesizedWhitespace(
                                first_line=TrailingWhitespace(
                                    whitespace=SimpleWhitespace(
                                        value='',
                                    ),
                                    comment=None,
                                    newline=Newline(
                                        value=None,
                                    ),
                                ),
                                empty_lines=[],
                                indent=True,
                                last_line=SimpleWhitespace(
                                    value='    ',
                                ),
                            ),
                        ),
                        rbrace=RightCurlyBrace(
                            whitespace_before=ParenthesizedWhitespace(
                                first_line=TrailingWhitespace(
                                    whitespace=SimpleWhitespace(
                                        value='',
                                    ),
                                    comment=None,
                                    newline=Newline(
                                        value=None,
                                    ),
                                ),
                                empty_lines=[],
                                indent=True,
                                last_line=SimpleWhitespace(
                                    value='',
                                ),
                            ),
                        ),
                        lpar=[],
                        rpar=[],
                    ),
                    semicolon=MaybeSentinel.DEFAULT,
                ),
            ],
            leading_lines=[],
            trailing_whitespace=TrailingWhitespace(
                whitespace=SimpleWhitespace(
                    value='    ',
                ),
                comment=None,
                newline=Newline(
                    value=None,
                ),
            ),
        )




class DomainChildrenDefinitionInserter(CSTTransformer):
    def __init__(self, parent, child, parents, children, parent_ref):
        self.parent = parent
        self.child = child
        self.parents = parents
        self.children = children
        self.parent_ref = parent_ref

    def visit_SimpleStatementLine(self, node):
        if not isinstance(node.body[0], Assign):
            return False

        if not node.body[0].targets[0].target.value == 'SCHEMA':
            return False

        return True


    def leave_Assign(self, original_node, updated_node):
        new_elements = []
        for item in original_node.value.elements[:-1]:
            new_elements.append(item)
        new_elements.append(original_node.value.elements[-1].with_changes (comma=get_comma()))
        new_elements.append(self.make_parent_ref())

        members = Dict(elements=new_elements,
                lbrace=LeftCurlyBrace(
                    whitespace_after=ParenthesizedWhitespace(
                        first_line=TrailingWhitespace(
                            whitespace=SimpleWhitespace(
                                value='',
                            ),
                            comment=None,
                            newline=Newline(
                                value=None,
                            ),
                        ),
                        empty_lines=[],
                        indent=True,
                        last_line=SimpleWhitespace(
                            value='    ',
                        ),
                    ),
                ),
                rbrace=RightCurlyBrace(
                    whitespace_before=ParenthesizedWhitespace(
                        first_line=TrailingWhitespace(
                            whitespace=SimpleWhitespace(
                                value='',
                            ),
                            comment=None,
                            newline=Newline(
                                value=None,
                            ),
                        ),
                        empty_lines=[],
                        indent=True,
                        last_line=SimpleWhitespace(
                            value='',
                        ),
                    ),
                ),
                lpar=[],
                rpar=[],
            )

        return updated_node.with_changes (value=members)


    def make_parent_ref(self):
        return DictElement(
            key=SimpleString(
                value=f"'{self.parent_ref}'",
                lpar=[],
                rpar=[],
            ),
            value=Dict(
                elements=[
                    DictElement(
                        key=SimpleString(
                            value="'type'",
                            lpar=[],
                            rpar=[],
                        ),
                        value=SimpleString(
                            value="'objectid'",
                            lpar=[],
                            rpar=[],
                        ),
                        comma=Comma(
                            whitespace_before=SimpleWhitespace(
                                value='',
                            ),
                            whitespace_after=ParenthesizedWhitespace(
                                first_line=TrailingWhitespace(
                                    whitespace=SimpleWhitespace(
                                        value='',
                                    ),
                                    comment=None,
                                    newline=Newline(
                                        value=None,
                                    ),
                                ),
                                empty_lines=[],
                                indent=True,
                                last_line=SimpleWhitespace(
                                    value='        ',
                                ),
                            ),
                        ),
                        whitespace_before_colon=SimpleWhitespace(
                            value='',
                        ),
                        whitespace_after_colon=SimpleWhitespace(
                            value=' ',
                        ),
                    ),
                    DictElement(
                        key=SimpleString(
                            value="'data_relation'",
                            lpar=[],
                            rpar=[],
                        ),
                        value=Dict(
                            elements=[
                                DictElement(
                                    key=SimpleString(
                                        value="'resource'",
                                        lpar=[],
                                        rpar=[],
                                    ),
                                    value=SimpleString(
                                        value=f"'{self.parents}'",
                                        lpar=[],
                                        rpar=[],
                                    ),
                                    comma=Comma(
                                        whitespace_before=SimpleWhitespace(
                                            value='',
                                        ),
                                        whitespace_after=ParenthesizedWhitespace(
                                            first_line=TrailingWhitespace(
                                                whitespace=SimpleWhitespace(
                                                    value='',
                                                ),
                                                comment=None,
                                                newline=Newline(
                                                    value=None,
                                                ),
                                            ),
                                            empty_lines=[],
                                            indent=True,
                                            last_line=SimpleWhitespace(
                                                value='            ',
                                            ),
                                        ),
                                    ),
                                    whitespace_before_colon=SimpleWhitespace(
                                        value='',
                                    ),
                                    whitespace_after_colon=SimpleWhitespace(
                                        value=' ',
                                    ),
                                ),
                                DictElement(
                                    key=SimpleString(
                                        value="'embeddable'",
                                        lpar=[],
                                        rpar=[],
                                    ),
                                    value=Name(
                                        value='True',
                                        lpar=[],
                                        rpar=[],
                                    ),
                                    comma=MaybeSentinel.DEFAULT,
                                    whitespace_before_colon=SimpleWhitespace(
                                        value='',
                                    ),
                                    whitespace_after_colon=SimpleWhitespace(
                                        value=' ',
                                    ),
                                ),
                            ],
                            lbrace=LeftCurlyBrace(
                                whitespace_after=ParenthesizedWhitespace(
                                    first_line=TrailingWhitespace(
                                        whitespace=SimpleWhitespace(
                                            value='',
                                        ),
                                        comment=None,
                                        newline=Newline(
                                            value=None,
                                        ),
                                    ),
                                    empty_lines=[],
                                    indent=True,
                                    last_line=SimpleWhitespace(
                                        value='            ',
                                    ),
                                ),
                            ),
                            rbrace=RightCurlyBrace(
                                whitespace_before=ParenthesizedWhitespace(
                                    first_line=TrailingWhitespace(
                                        whitespace=SimpleWhitespace(
                                            value='',
                                        ),
                                        comment=None,
                                        newline=Newline(
                                            value=None,
                                        ),
                                    ),
                                    empty_lines=[],
                                    indent=True,
                                    last_line=SimpleWhitespace(
                                        value='        ',
                                    ),
                                ),
                            ),
                            lpar=[],
                            rpar=[],
                        ),
                        comma=MaybeSentinel.DEFAULT,
                        whitespace_before_colon=SimpleWhitespace(
                            value='',
                        ),
                        whitespace_after_colon=SimpleWhitespace(
                            value=' ',
                        ),
                    ),
                ],
                lbrace=LeftCurlyBrace(
                    whitespace_after=ParenthesizedWhitespace(
                        first_line=TrailingWhitespace(
                            whitespace=SimpleWhitespace(
                                value='',
                            ),
                            comment=None,
                            newline=Newline(
                                value=None,
                            ),
                        ),
                        empty_lines=[],
                        indent=True,
                        last_line=SimpleWhitespace(
                            value='        ',
                        ),
                    ),
                ),
                rbrace=RightCurlyBrace(
                    whitespace_before=ParenthesizedWhitespace(
                        first_line=TrailingWhitespace(
                            whitespace=SimpleWhitespace(
                                value='',
                            ),
                            comment=None,
                            newline=Newline(
                                value=None,
                            ),
                        ),
                        empty_lines=[],
                        indent=True,
                        last_line=SimpleWhitespace(
                            value='    ',
                        ),
                    ),
                ),
                lpar=[],
                rpar=[],
            ),
            comma=MaybeSentinel.DEFAULT,
            whitespace_before_colon=SimpleWhitespace(
                value='',
            ),
            whitespace_after_colon=SimpleWhitespace(
                value=' ',
            ),
        )





class DomainDefinitionInserter(CSTTransformer):
    def __init__(self, parent, child, parents, children, parent_ref):
        self.parent = parent
        self.child = child
        self.parents = parents
        self.children = children
        self.parent_ref = parent_ref

    def visit_SimpleStatementLine(self, node):
        if not isinstance(node.body[0], Assign):
            return False

        if not node.body[0].targets[0].target.value == 'DOMAIN_RELATIONS':
            return False

        return True


    def leave_Assign(self, original_node, updated_node):
        new_elements = []
        if original_node.value.elements:
            for item in original_node.value.elements[:-1]:
                new_elements.append(item)
            new_elements.append(original_node.value.elements[-1].with_changes (comma=get_comma()))
        new_elements.append(self.make_domain_relation())

        relations = Dict(elements=new_elements,
                lbrace=LeftCurlyBrace(
                    whitespace_after=ParenthesizedWhitespace(
                        first_line=TrailingWhitespace(
                            whitespace=SimpleWhitespace(
                                value='',
                            ),
                            comment=None,
                            newline=Newline(
                                value=None,
                            ),
                        ),
                        empty_lines=[],
                        indent=True,
                        last_line=SimpleWhitespace(
                            value='    ',
                        ),
                    ),
                ),
                rbrace=RightCurlyBrace(
                    whitespace_before=ParenthesizedWhitespace(
                        first_line=TrailingWhitespace(
                            whitespace=SimpleWhitespace(
                                value='',
                            ),
                            comment=None,
                            newline=Newline(
                                value=None,
                            ),
                        ),
                        empty_lines=[],
                        indent=True,
                        last_line=SimpleWhitespace(
                            value='',
                        ),
                    ),
                ),
                lpar=[],
                rpar=[],
            )

        return updated_node.with_changes (value=relations)


    def make_domain_relation(self):
        return DictElement(
            key=SimpleString(
                value=f"'{self.parents}_{self.children}'",
                lpar=[],
                rpar=[],
            ),
            value=Dict(
                elements=[
                    DictElement(
                        key=SimpleString(
                            value="'schema'",
                            lpar=[],
                            rpar=[],
                        ),
                        value=Attribute(
                            value=Name(
                                value=f'{self.children}',
                                lpar=[],
                                rpar=[],
                            ),
                            attr=Name(
                                value='SCHEMA',
                                lpar=[],
                                rpar=[],
                            ),
                            dot=Dot(
                                whitespace_before=SimpleWhitespace(
                                    value='',
                                ),
                                whitespace_after=SimpleWhitespace(
                                    value='',
                                ),
                            ),
                            lpar=[],
                            rpar=[],
                        ),
                        comma=Comma(
                            whitespace_before=SimpleWhitespace(
                                value='',
                            ),
                            whitespace_after=ParenthesizedWhitespace(
                                first_line=TrailingWhitespace(
                                    whitespace=SimpleWhitespace(
                                        value='',
                                    ),
                                    comment=None,
                                    newline=Newline(
                                        value=None,
                                    ),
                                ),
                                empty_lines=[],
                                indent=True,
                                last_line=SimpleWhitespace(
                                    value='        ',
                                ),
                            ),
                        ),
                        whitespace_before_colon=SimpleWhitespace(
                            value='',
                        ),
                        whitespace_after_colon=SimpleWhitespace(
                            value=' ',
                        ),
                    ),
                    DictElement(
                        key=SimpleString(
                            value="'url'",
                            lpar=[],
                            rpar=[],
                        ),
                        value=SimpleString(
                            value=f'\'{self.parents}/<regex("[a-f0-9]{{24}}"):{self.parent_ref}>/{self.children}\'',
                            lpar=[],
                            rpar=[],
                        ),
                        comma=Comma(
                            whitespace_before=SimpleWhitespace(
                                value='',
                            ),
                            whitespace_after=ParenthesizedWhitespace(
                                first_line=TrailingWhitespace(
                                    whitespace=SimpleWhitespace(
                                        value='',
                                    ),
                                    comment=None,
                                    newline=Newline(
                                        value=None,
                                    ),
                                ),
                                empty_lines=[],
                                indent=True,
                                last_line=SimpleWhitespace(
                                    value='        ',
                                ),
                            ),
                        ),
                        whitespace_before_colon=SimpleWhitespace(
                            value='',
                        ),
                        whitespace_after_colon=SimpleWhitespace(
                            value=' ',
                        ),
                    ),
                    DictElement(
                        key=SimpleString(
                            value="'resource_title'",
                            lpar=[],
                            rpar=[],
                        ),
                        value=SimpleString(
                            value=f"'{self.children}'",
                            lpar=[],
                            rpar=[],
                        ),
                        comma=Comma(
                            whitespace_before=SimpleWhitespace(
                                value='',
                            ),
                            whitespace_after=ParenthesizedWhitespace(
                                first_line=TrailingWhitespace(
                                    whitespace=SimpleWhitespace(
                                        value='',
                                    ),
                                    comment=None,
                                    newline=Newline(
                                        value=None,
                                    ),
                                ),
                                empty_lines=[],
                                indent=True,
                                last_line=SimpleWhitespace(
                                    value='        ',
                                ),
                            ),
                        ),
                        whitespace_before_colon=SimpleWhitespace(
                            value='',
                        ),
                        whitespace_after_colon=SimpleWhitespace(
                            value=' ',
                        ),
                    ),
                    DictElement(
                        key=SimpleString(
                            value="'datasource'",
                            lpar=[],
                            rpar=[],
                        ),
                        value=Dict(
                            elements=[
                                DictElement(
                                    key=SimpleString(
                                        value="'source'",
                                        lpar=[],
                                        rpar=[],
                                    ),
                                    value=SimpleString(
                                        value=f"'{self.children}'",
                                        lpar=[],
                                        rpar=[],
                                    ),
                                    comma=MaybeSentinel.DEFAULT,
                                    whitespace_before_colon=SimpleWhitespace(
                                        value='',
                                    ),
                                    whitespace_after_colon=SimpleWhitespace(
                                        value=' ',
                                    ),
                                ),
                            ],
                            lbrace=LeftCurlyBrace(
                                whitespace_after=SimpleWhitespace(
                                    value='',
                                ),
                            ),
                            rbrace=RightCurlyBrace(
                                whitespace_before=SimpleWhitespace(
                                    value='',
                                ),
                            ),
                            lpar=[],
                            rpar=[],
                        ),
                        comma=MaybeSentinel.DEFAULT,
                        whitespace_before_colon=SimpleWhitespace(
                            value='',
                        ),
                        whitespace_after_colon=SimpleWhitespace(
                            value=' ',
                        ),
                    ),
                ],
                lbrace=LeftCurlyBrace(
                    whitespace_after=ParenthesizedWhitespace(
                        first_line=TrailingWhitespace(
                            whitespace=SimpleWhitespace(
                                value='',
                            ),
                            comment=None,
                            newline=Newline(
                                value=None,
                            ),
                        ),
                        empty_lines=[],
                        indent=True,
                        last_line=SimpleWhitespace(
                            value='        ',
                        ),
                    ),
                ),
                rbrace=RightCurlyBrace(
                    whitespace_before=ParenthesizedWhitespace(
                        first_line=TrailingWhitespace(
                            whitespace=SimpleWhitespace(
                                value='',
                            ),
                            comment=None,
                            newline=Newline(
                                value=None,
                            ),
                        ),
                        empty_lines=[],
                        indent=True,
                        last_line=SimpleWhitespace(
                            value='    ',
                        ),
                    ),
                ),
                lpar=[],
                rpar=[],
            ),
            comma=MaybeSentinel.DEFAULT,
            whitespace_before_colon=SimpleWhitespace(
                value='',
            ),
            whitespace_after_colon=SimpleWhitespace(
                value=' ',
            )
        )


def add_links_to_child_hooks(parent, child, parents, children, parent_ref):
    with open(f'hooks/{children}.py', 'r') as source:
        tree = parse_module(source.read())

    inserter = ChildLinksInserter(parent, child, parents, children, parent_ref)
    new_tree = tree.visit(inserter)

    with open(f'hooks/{children}.py', 'w') as source:
        source.write(new_tree.code)


def add_links_to_parent_hooks(parent, child, parents, children, parent_ref):
    with open(f'hooks/{parents}.py', 'r') as source:
        tree = parse_module(source.read())

    inserter = ParentLinksInserter(parent, child, parents, children, parent_ref)
    new_tree = tree.visit(inserter)

    with open(f'hooks/{parents}.py', 'w') as source:
        source.write(new_tree.code)


def add_to_domain_init(parent, child, parents, children, parent_ref):
    with open('domain/__init__.py', 'r') as source:
        tree = parse_module(source.read())

    inserter = DomainDefinitionInserter(parent, child, parents, children, parent_ref)
    new_tree = tree.visit(inserter)

    with open('domain/__init__.py', 'w') as source:
        source.write(new_tree.code)


def add_to_domain_child(parent, child, parents, children, parent_ref):
    with open(f'domain/{children}.py', 'r') as source:
        tree = parse_module(source.read())

    inserter = DomainChildrenDefinitionInserter(parent, child, parents, children, parent_ref)
    new_tree = tree.visit(inserter)

    with open(f'domain/{children}.py', 'w') as source:
        source.write(new_tree.code)


def main():
    parser = argparse.ArgumentParser('mkrel', description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('parent', help='The name of the parent resource to create the link from.')
    parser.add_argument('child', help='The name of the child resource to create the link to.')
    parser.add_argument('-p', '--as_parent_ref', help='change name of related rel to "parent" (instead of the name of the parent)', action='store_true')

    args = parser.parse_args()
    parent, parents = singular, plural = get_pair(args.parent)  # TODO: validate, safe name, etc.
    child, children = singular, plural = get_pair(args.child)  # TODO: validate, safe name, etc.
    parent_ref = '_parent_ref' if args.as_parent_ref else f'_{parent}_ref'

    if os.path.exists('eve_service.py') and os.path.exists('domain'):
        print(f'Creating link rel from {parent} (parent) to {child} (child)')

        add_to_domain_init(parent, child, parents, children, parent_ref)
        add_to_domain_child(parent, child, parents, children, parent_ref)
        add_links_to_parent_hooks(parent, child, parents, children, parent_ref)
        add_links_to_child_hooks(parent, child, parents, children, parent_ref)


if __name__ == '__main__':
    main()
