using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using InABox.Clients; using InABox.Core; namespace Comal.Classes { public abstract class BaseKanbanSubscriberSet { private readonly List _subscribers = new List(); protected BaseKanbanSubscriberSet(IEnumerable kanbanids) { _subscribers.Clear(); var result = DoQuery( new Filter(x => x.Kanban.ID).InList(kanbanids.ToArray()), new Columns(x => x.ID).Add(x => x.Kanban.ID).Add(x => x.Employee.ID).Add(x => x.Assignee).Add(x => x.Manager) .Add(x => x.Observer)); if (result.Rows.Any()) _subscribers.AddRange(result.Rows.Select(x => x.ToObject())); } public void Save(bool wait = true) { var update = Task.Run(() => { var updates = _subscribers.Where(x => (x.Manager || x.Assignee || x.Observer) && (x.IsChanged() || Equals(x.ID, Guid.Empty))).ToArray(); if (updates.Any()) DoSave(updates); }); var delete = Task.Run(() => { var deletes = _subscribers.Where(x => !x.Manager && !x.Assignee && !x.Observer).ToArray(); if (deletes.Any()) DoDelete(deletes); }); if (wait) Task.WaitAll(update, delete); } private KanbanSubscriber EnsureSubscriber(Guid kanbanid, Guid employeeid) { var subscriber = _subscribers.FirstOrDefault(x => Equals(x.Kanban.ID, kanbanid) && Equals(x.Employee.ID, employeeid)); if (subscriber == null) { subscriber = new KanbanSubscriber(); subscriber.Kanban.ID = kanbanid; subscriber.Employee.ID = employeeid; _subscribers.Add(subscriber); } return subscriber; } public void EnsureManager(Guid kanbanid, Guid employeeid) { if(employeeid == Guid.Empty) { return; } var manager = EnsureSubscriber(kanbanid, employeeid); // No-one else can be a manager var others = _subscribers.Where(x => Equals(x.Kanban.ID, kanbanid)).ToArray(); foreach (var other in others) { if(other != manager) { other.Manager = false; } } // only this one! manager.Manager = true; } public void EnsureAssignee(Guid kanbanid, Guid employeeid) { if (employeeid == Guid.Empty) { return; } var assignee = EnsureSubscriber(kanbanid, employeeid); // No-one else can be a assignee var others = _subscribers.Where(x => Equals(x.Kanban.ID, kanbanid)).ToArray(); foreach (var other in others) { if (other != assignee) { other.Assignee = false; } } // only this one! assignee.Assignee = true; } public void EnsureObserver(Guid kanbanid, Guid employeeid) { if (employeeid == Guid.Empty) { return; } var observer = EnsureSubscriber(kanbanid, employeeid); // Employee can only be an observer once var subscribers = _subscribers.Where(x => Equals(x.Kanban.ID, kanbanid) && Equals(x.Employee.ID, employeeid)).ToArray(); foreach (var subscriber in subscribers) { if (subscriber != observer) { subscriber.Observer = false; } } observer.Observer = true; } protected abstract CoreTable DoQuery(Filter filter, Columns columns); protected abstract void DoSave(IEnumerable updates); protected abstract void DoDelete(KanbanSubscriber[] deletes); } public class ClientKanbanSubscriberSet : BaseKanbanSubscriberSet { public ClientKanbanSubscriberSet(IEnumerable kanbanids) : base(kanbanids) { } protected override void DoSave(IEnumerable updates) => new Client().Save(updates, ""); protected override void DoDelete(KanbanSubscriber[] deletes) => new Client().Delete(deletes, ""); protected override CoreTable DoQuery(Filter filter, Columns columns) => new Client().Query(filter, columns); } }