"""Some fancy code generation"""
import json

from app.backend.rpc import get_active_rpc_client, DecimalEncoder
from app.models import init_profile_db


scan = (
    'getaddresses',
    'getbalance',
    'getblockchaininfo',
    'getblockchainparams',
    'getblockcount',
    'getinfo',
    'getmultibalances',
    'getruntimeparams',
    'listaddresses',
    'listblocks',
    'listpermissions',
    'listwallettransactions',
)


def generate_api_sample_responses():
    """Creates sample response json data in .scratch folder.

    Note: Calls rpc.RpcClient methods with their default args.
    Other args may yield different json structures!
    """
    init_profile_db()
    client = get_active_rpc_client()
    for method in scan:
        result = getattr(client, method)()
        fp = '.scratch/{}.json'.format(method)
        json.dump(result, open(fp, 'w'), indent=4, cls=DecimalEncoder)


module_header = """# -*- coding: utf-8 -*-
# WARNING: Autogenerated code. Do not edit manually. Regenerate with codegen.py

"""

class_template = """
class {classname}:

    def __init__(self, **kwargs):
        self._kwargs = kwargs
        {setters}
    
    def as_dict(self):
        return self._kwargs
        
    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self._kwargs == other._kwargs
        else:
            return False
"""

generate = (
    'getblockchaininfo',
    'getinfo',
    'getruntimeparams',
)


def generate_classes():
    init_profile_db()
    client = get_active_rpc_client()

    class_blocks = []
    for method in generate:
        result = getattr(client, method)()
        classname = method.title()
        setters = []
        for field in result['result'].keys():
            setter = 'self.{} = kwargs["{}"]'.format(field, field)
            setters.append(setter)
        setters = '\n        '.join(setters)
        class_block = class_template.format(
            classname=classname, setters=setters
        )
        class_blocks.append(class_block)
    module_code = module_header + "\n".join(class_blocks)
    with open('app/responses.py', 'w') as outf:
        outf.write(module_code)


if __name__ == '__main__':
    generate_api_sample_responses()
    generate_classes()
    print('See sample api responses in .scratch')
    print('See generated code at app/responses.py')
