// Autogenerated with DRAKON Editor 1.25
using System;
using System.Linq;
using System.Collections.Generic;

class Bar {
    public interface IBaseRecord
    {
        int Id { get; }
    }
    private interface IDelRecord
    {
        void PreDeleteOuter(System.Collections.Generic.HashSet<IDelRecord> deletionList, bool master);
        void EnsureCanDelete(System.Collections.Generic.HashSet<IDelRecord> deletionList);
        void DoDelete(Bar db, System.Collections.Generic.HashSet<IDelRecord> deletionList);
    }
    public interface IEmployee : IBaseRecord {
        string Name { get; set; }
        int Type { get; set; }
    }
    private int _next_employee = 1;
    private readonly Dictionary<int, Employee> _employee_pk = new Dictionary<int, Employee>();
    private class Employee : IEmployee, IDelRecord {
        public readonly int _id;
        public int Id { get { return _id; } }
        public Employee(int id) {
            _id = id;
        }
        public string _name;
        public string Name {
            get { return _name; }
            set { _name = value; }
        }
        public int _type;
        public int Type {
            get { return _type; }
            set { _type = value; }
        }
        public virtual void EnsureCanDelete(System.Collections.Generic.HashSet<IDelRecord> deletionList) {
        }
        public virtual void DoDelete(Bar db, System.Collections.Generic.HashSet<IDelRecord> deletionList) {
            db._employee_pk.Remove(_id);
        }
        public virtual void PreDeleteOuter(System.Collections.Generic.HashSet<IDelRecord> deletionList, bool master) {
            if (deletionList.Contains(this)) {
                return;
            } else {
                deletionList.Add(this);
            }
            PreDeleteInner(deletionList);
        }
        public virtual void PreDeleteInner(System.Collections.Generic.HashSet<IDelRecord> deletionList) {
        }
    }
    public IEmployee InsertEmployee(int id) {
        if ( id == 0 ) {
            id = _next_employee;
        } else {
            if (_employee_pk.ContainsKey(id)) {
                string className = _employee_pk[id].GetType().Name;
                throw new ArgumentException(String.Format(
                    "'{0}' with id '{1}' already exists.",
                    className, id));
            }
        }
        if ( id >= _next_employee ) {
            _next_employee = id + 1;
        }
        var _record_ = new Employee(id);
        _employee_pk[id] = _record_;
        return _record_;
    }
    public IEmployee GetEmployee(int id) {
        Employee _record_;
        if (!_employee_pk.TryGetValue(id, out _record_)) {
            return null;
        }
        return _record_;
    }
    public int EmployeeCount() {
        return _employee_pk.Count;
    }
    public IEnumerable<IEmployee> EachEmployee() {
        foreach (KeyValuePair<int, Employee> record in _employee_pk) {
            yield return record.Value;
        }
    }
    public void DeleteEmployee(IEmployee record) {
        if (record == null) return;
        Employee _record_;
        var deletionList = new System.Collections.Generic.HashSet<IDelRecord>();
        if ( !_employee_pk.TryGetValue(record.Id, out _record_)) {
            throw new ArgumentException(String.Format(
                "'Employee' with id '{0}' does not exist.",
                record.Id));
        }
        _record_.PreDeleteOuter(deletionList, false);
        foreach (IDelRecord item in deletionList) {
            item.EnsureCanDelete(deletionList);
        }
        foreach (IDelRecord item in deletionList) {
            item.DoDelete(this, deletionList);
        }
    }

    public static void Equal(object expected, object actual) {
        // item 134
        if (Object.Equals(expected, actual)) {
            
        } else {
            // item 116
            if (expected is System.Collections.IEnumerable) {
                // item 122
                if (actual is System.Collections.IEnumerable) {
                    // item 125
                    var expectedEn = (System.Collections.IEnumerable)expected;
                    var actualEn = (System.Collections.IEnumerable)actual;
                    // item 140
                    List<object> exList = expectedEn.Cast<object>().ToList();
                    List<object> acList = actualEn.Cast<object>().ToList();
                    // item 126
                    if (exList.Count == acList.Count) {
                        // item 1290001
                        int i = 0;
                        while (true) {
                            // item 1290002
                            if (i < exList.Count) {
                                
                            } else {
                                break;
                            }
                            // item 131
                            Equal(exList[i], acList[i]);
                            // item 1290003
                            i++;
                        }
                    } else {
                        // item 128
                        throw new Exception("Collections have different sizes");
                    }
                } else {
                    // item 124
                    throw new Exception("Both should be IEnumerable");
                }
            } else {
                // item 119
                if (actual is System.Collections.IEnumerable) {
                    // item 120
                    throw new Exception("Both should be IEnumerable");
                } else {
                    // item 132
                    throw new Exception("Objects are not equal.");
                }
            }
        }
    }

    public static void Main() {
        IEnumerator<Bar.IEmployee> _it90 = null;
        Bar.IEmployee person = default(Bar.IEmployee);
        // item 19
        Bar db = new Bar();
        // item 35
        Equal(null, db.GetEmployee(400));
        // item 108
        Equal(0, db.EmployeeCount());
        // item 76
        Bar.IEmployee john = db.InsertEmployee(400);
        // item 77
        Equal(400, john.Id);
        // item 78
        Equal(john, db.GetEmployee(400));
        // item 75
        Bar.IEmployee mark = db.InsertEmployee(0);
        // item 83
        NotEqual(mark, john);
        NotEqual(mark.Id, john.Id);
        // item 69
        Equal(null, john.Name);
        Equal(null, mark.Name);
        // item 67
        john.Name = "John";
        john.Type = 100;
        // item 68
        mark.Name = "Mark";
        mark.Type = 200;
        // item 113
        Equal("John", john.Name);
        Equal(100, john.Type);
        Equal("Mark", mark.Name);
        Equal(200, mark.Type);
        // item 92
        List<string> names = new List<string>();
        // item 900001
        _it90 = ((IEnumerable<Bar.IEmployee>)db.EachEmployee()).GetEnumerator();
        while (true) {
            // item 900002
            if (_it90.MoveNext()) {
                
            } else {
                break;
            }
            // item 900004
            person = _it90.Current;
            // item 93
            names.Add(person.Name);
        }
        // item 95
        names.Sort();
        // item 114
        Equal(new string[] { "John", "Mark" }, names);
        // item 102
        Equal(2, db.EmployeeCount());
        // item 99
        int johnId = john.Id;
        int markId = mark.Id;
        // item 100
        db.DeleteEmployee(john);
        db.DeleteEmployee(mark);
        // item 101
        Equal(null, db.GetEmployee(johnId));
        Equal(null, db.GetEmployee(markId));
        // item 115
        Equal(0, db.EmployeeCount());
    }

    public static void NotEqual(object left, object right) {
        // item 136
        if (Object.Equals(left, right)) {
            // item 139
            throw new Exception("Objects are equal.");
        } else {
            
        }
    }
}

