from .operation import *


def get_curve_schema(name: str) -> dict[str, dict[str, Any]]:
    return { 'id'     : {'type': 'str'  , 'optional': False , 'readonly': True },
             'coords' : {'type': 'list' , 'optional': False , 'readonly': False, 
                           'element': { 'x'  : {'type': 'float' , 'optional': False , 'readonly': False }, 
                                        'y'  : {'type': 'float' , 'optional': False , 'readonly': False } }}}


def get_curve(name: str, id: str) -> dict[str, Any]:
    cus = read_all(name, f"select * from curves where id = '{id}'")
    cs = []
    for r in cus:
        cs.append({ 'x': float(r['x']), 'y': float(r['y']) })
    return { 'id': id, 'coords': cs }


def set_curve(name: str, cs: ChangeSet) -> ChangeSet:
    id = cs.operations[0]['id']

    old = get_curve(name, id)
    new = { 'id': id, 'coords': [] }

    f_id = f"'{id}'"

    # TODO: transaction ?
    redo_sql = f"delete from curves where id = {f_id};"
    redo_sql += f"\ndelete from _curve where id = {f_id};"
    if len(cs.operations[0]['coords']) > 0:
        redo_sql += f"\ninsert into _curve (id) values ({f_id});"
    for xy in cs.operations[0]['coords']:
        x, y = float(xy['x']), float(xy['y'])
        f_x, f_y = x, y
        redo_sql += f"\ninsert into curves (id, x, y) values ({f_id}, {f_x}, {f_y});"
        new['coords'].append({ 'x': x, 'y': y })

    undo_sql = f"delete from curves where id = {f_id};"
    undo_sql += f"\ndelete from _curve where id = {f_id};"
    if len(old['coords']) > 0:
        undo_sql += f"\ninsert into _curve (id) values ({f_id});"
    for xy in old['coords']:
        f_x, f_y = xy['x'], xy['y']
        undo_sql += f"\ninsert into curves (id, x, y) values ({f_id}, {f_x}, {f_y});"

    redo_cs = g_update_prefix | { 'type': 'curve' } | new
    undo_cs = g_update_prefix | { 'type': 'curve' } | old

    return execute_command(name, redo_sql, undo_sql, redo_cs, undo_cs)
