/* Autogenerated with DRAKON Editor 1.23 */
#include "simple.h"

#include <memory.h>
#include <stdio.h>
static int add_to_list(
    employee* item,
    void* user
);

static int str_eq(
    const char* expected,
    const string8* actual
);







struct simple {
    tobject base;
    array_table employee;
    int error_code;
};
static type_info_t simple_t = {
	OBJECT_SIGNATURE,
	"simple",
	(destructor_fun)simple_destroy
};
struct employee {
    row_base _row;
    string8* name;
    int type;
    int* ext;
};


static int
delete_generic(simple* db,
    obj_list* deletion_list);


static int
ensure_can_delete(simple* db,
    void* record,
    obj_list* deletion_list);


static void
do_delete(simple* db,
    void* record,
    obj_list* deletion_list,
    int unlink);


static int
record_destructor(void* record,
    void* dbv);


static int
employee_pre_delete(simple* db,
    employee* record,
    obj_list* deletion_list,
    int master);


static int
employee_ensure_can_delete(simple* db,
    employee* record,
    obj_list* deletion_list);


static void
employee_do_delete(simple* db,
    employee* record,
    obj_list* deletion_list,
    int unlink);


simple* /* own */
simple_create(void) {
    simple* me = allocate_memory(sizeof(simple));
    me->base.type = &simple_t;
    array_table_init(&me->employee, "employee");
    me->employee.do_delete = (dd_fun)employee_do_delete;
    me->employee.ensure_can_delete = (ensure_cd_fun)employee_ensure_can_delete;
    return me;
}


void
simple_destroy(simple* me /* own. null */) {
    if (!me) return;
    ENSURE(me->base.type == &simple_t)
    simple_foreach_employee(
        me,
        (employee_fun)record_destructor,
        me);
    array_table_cleanup(&me->employee);
    free_memory(me, sizeof(simple));
}


int
simple_error(const simple* db) {
    return db->error_code;
}


int
employee_id(const employee* me) {
    return me->_row.id;
}


employee* /* null */
simple_get_employee(simple* db,
    int rec_id) {
    if (rec_id < 0) return 0;
    if (rec_id >= db->employee.next) return 0;
    return db->employee.items[rec_id];
}


string8* /* null */
employee_name(employee* me) {
    return me->name;
}


const string8* /* null */
employee_cget_name(const employee* me) {
    return me->name;
}


void
employee_set_name(employee* me,
    string8* value /* own. null */) {
    if (me->name == value) return;
    if (me->name) {
        string8_destroy(me->name);
    }
    me->name = value;
}


int
employee_type(const employee* me) {
    return me->type;
}


void
employee_set_type(employee* me,
    int value) {
    me->type = value;
}


int* /* null */
employee_ext(const employee* me) {
    return me->ext;
}


void
employee_set_ext(employee* me,
    int* value /* null */) {
    me->ext = value;
}


employee* /* null */
simple_insert_employee(simple* db,
    string8* name /* own. null */,
    int type) {
    employee* _record_;
    int rec_id;
    _record_ = 0;
    _record_ = allocate_memory(sizeof(employee));
    rec_id = array_table_insert(&db->employee, _record_);
    _record_->_row.id = rec_id;
    _record_->_row.table = &db->employee;
    _record_->name = name;
    _record_->type = type;
    return _record_;
}


int
simple_delete_employee(simple* db,
    employee* record /* null */) {
    obj_list* deletion_list;
    int deleted = 0;
    if (!record) return 0;
    deletion_list = obj_list_create(0);
    ENSURE(record == simple_get_employee(db, record->_row.id))
    if (employee_pre_delete(db, record, deletion_list, 0)) {
        deleted = delete_generic(db, deletion_list);
    }
    obj_list_destroy(deletion_list);
    return deleted;
}


int
simple_employee_count(const simple* db) {
    return db->employee.count;
}


int
simple_foreach_employee(simple* db,
    employee_fun visitor,
    void* user_data /* null */) {
    int i, n;
    employee* current;
    n = db->employee.next;
    for (i = 0; i < n; i++) {
        current = db->employee.items[i];
        if (current) {
            if (visitor(current, user_data)) return 1;
        }
    }
    return 0;
}


static int
delete_generic(simple* db,
    obj_list* deletion_list) {
    void* record;
    int i, n;
    n = obj_list_length(deletion_list);
    for (i = 0; i < n; i++) {
        record = obj_list_get(deletion_list, i);
        if (!ensure_can_delete(db, record, deletion_list)) {
            return 0;
        }
    }
    for (i = 0; i < n; i++) {
        record = obj_list_get(deletion_list, i);
        do_delete(db, record, deletion_list, 1);
    }
    return 1;
}


static int
ensure_can_delete(simple* db,
    void* record,
    obj_list* deletion_list) {
    row_base* row = record;
    return row->table->ensure_can_delete(
        db,
        record,
        deletion_list);
}


static void
do_delete(simple* db,
    void* record,
    obj_list* deletion_list,
    int unlink) {
    row_base* row = record;
    row->table->do_delete(
        db,
        record,
        deletion_list,
        unlink);
}


static int
record_destructor(void* record,
    void* dbv) {
    simple* db = dbv;
    do_delete(
        db,
        record,
        0,
        0);
    return 0;
}


static int
employee_pre_delete(simple* db,
    employee* record,
    obj_list* deletion_list,
    int master) {
    if (obj_list_contains(deletion_list, record)) {
        return 1;
    } else {
        obj_list_add(deletion_list, record);
    }
    return 1;
}


static int
employee_ensure_can_delete(simple* db,
    employee* record,
    obj_list* deletion_list) {
    return 1;
}


static void
employee_do_delete(simple* db,
    employee* record,
    obj_list* deletion_list,
    int unlink) {
    if (unlink) {
        array_table_delete(&db->employee, record->_row.id);
    }
    string8_destroy(record->name);
    free_memory(record, sizeof(employee));
}
static int add_to_list(
    employee* item,
    void* user
) {
    // item 136
    obj_list* list = user;
    /* item 137 */
    ENSURE(item)
    ENSURE(user)
    /* item 138 */
    obj_list_add(list, item);
    /* item 144 */
    return 0;
    
}

static int str_eq(
    const char* expected,
    const string8* actual
) {
    // item 129
    int result;
    /* item 126 */
    string8* exp = string8_from_cstr(expected, 50); // own
    /* item 130 */
    result = string8_equal(actual, exp);
    /* item 127 */
    string8_destroy(exp);
    /* item 128 */
    return result;
    
}

int main(
    int argc,
    char** argv
) {
    // item 118
    employee* john;
    employee* mark;
    int johnId, markId;
    /* item 116 */
    simple* db; // own
    obj_list* emps; // own
    /* item 19 */
    db = simple_create();
    emps = obj_list_create(0);
    /* item 35 */
    ENSURE(simple_get_employee(db, 400) == 0)
    /* item 108 */
    ENSURE(simple_employee_count(db) == 0)
    /* item 76 */
    john = simple_insert_employee(
    	db,
    	string8_from_cstr("foo", 100),
    	3
    );
    /* item 77 */
    johnId = employee_id(john);
    /* item 78 */
    ENSURE(simple_get_employee(db, johnId) == john)
    /* item 75 */
    mark = simple_insert_employee(
    	db,
    	string8_from_cstr("bar", 3),
    	8
    );
    /* item 141 */
    markId = employee_id(mark);
    /* item 83 */
    ENSURE(mark != john)
    ENSURE(employee_id(mark) != employee_id(john))
    /* item 142 */
    ENSURE(str_eq("foo", employee_cget_name(john)))
    ENSURE(3 == employee_type(john))
    ENSURE(0 == employee_ext(john))
    ENSURE(str_eq("bar", employee_cget_name(mark)))
    ENSURE(8 == employee_type(mark))
    ENSURE(0 == employee_ext(mark))
    /* item 119 */
    employee_set_name(
    	john,
    	string8_from_cstr("John", 100));
    employee_set_type(john, 100);
    /* item 120 */
    employee_set_name(
    	mark,
    	string8_from_cstr("Mark", 100));
    employee_set_type(mark, 200);
    /* item 113 */
    ENSURE(str_eq("John", employee_cget_name(john)))
    ENSURE(100 == employee_type(john))
    ENSURE(str_eq("Mark", employee_cget_name(mark)))
    ENSURE(200 == employee_type(mark))
    /* item 92 */
    simple_foreach_employee(
    	db,
    	add_to_list, 
    	emps
    );
    /* item 139 */
    ENSURE(obj_list_length(emps) == 2)
    /* item 140 */
    ENSURE(obj_list_contains(emps, john))
    ENSURE(obj_list_contains(emps, mark))
    /* item 102 */
    ENSURE(2 == simple_employee_count(db))
    /* item 100 */
    simple_delete_employee(db, john);
    /* item 101 */
    ENSURE(simple_get_employee(db, johnId) == 0)
    ENSURE(simple_get_employee(db, markId) == mark)
    /* item 115 */
    ENSURE(simple_employee_count(db) == 1)
    /* item 147 */
    obj_list_clear(emps);
    /* item 145 */
    simple_foreach_employee(
    	db,
    	add_to_list, 
    	emps
    );
    /* item 146 */
    ENSURE(obj_list_length(emps) == 1)
    /* item 148 */
    ENSURE(!obj_list_contains(emps, john))
    ENSURE(obj_list_contains(emps, mark))
    /* item 117 */
    object_destroy(db);
    object_destroy(emps);
    /* item 143 */
    return 0;
    
}



