using System; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using InABox.Clients; namespace InABox.Core { public interface IDigitalFormDocumentHandler { void LoadDocument(Guid id, Action callback); byte[] LoadDocument(Guid id); Guid SaveDocument(byte[] data); void Run(); void Stop(); } public abstract class DigitalFormDocumentHandler : IDigitalFormDocumentHandler { private static String FileName(Guid id) => $"{id}.formdocument"; protected abstract String CachePath { get; } protected abstract bool IsConnected { get; } private static Action? _status; public byte[] LoadDocument(Guid id) { var fullpath = Path.Combine(CachePath, FileName(id)); if (File.Exists(fullpath)) return File.ReadAllBytes(fullpath); var result = new Client().Query( new Filter(x => x.FileName).IsEqualTo(FileName(id)), null, null ).Rows.FirstOrDefault()?.Get(c=>c.Data); return result; } public void LoadDocument(Guid id, Action callback) { var fullpath = Path.Combine(CachePath, FileName(id)); if (File.Exists(fullpath)) callback(File.ReadAllBytes(fullpath)); else { new Client().Query( new Filter(x => x.FileName).IsEqualTo(FileName(id)), null, null, CoreRange.All, (o, e) => { var row = o?.Rows.FirstOrDefault(); if (row != null) callback(row.Get(c => c.Data)); } ); } } public Guid SaveDocument(byte[] data) { Guid result = Guid.NewGuid(); var filename = Path.Combine(CachePath, FileName(result)); File.WriteAllBytes(filename,data); return result; } private CancellationTokenSource? _cancel; public void Stop() { if (_cancel != null) { _cancel.Cancel(); _cancel = null; } } protected DigitalFormDocumentHandler(Action status) { _status = status; } public void Run() { Stop(); _cancel = new CancellationTokenSource(); Task.Run( () => { bool? previouslyActive = null; while (_cancel?.IsCancellationRequested != true) { var file = Directory.EnumerateFiles(CachePath, "*.formdocument") .FirstOrDefault(); var isActive = !String.IsNullOrWhiteSpace(file); if (isActive != previouslyActive) { previouslyActive = isActive; _status?.Invoke(isActive); } if (!String.IsNullOrWhiteSpace(file) && File.Exists(file) && IsConnected) { var data = File.ReadAllBytes(file); var document = new Document() { FileName = Path.GetFileName(file), Data = data, CRC = CoreUtils.CalculateCRC(data), TimeStamp = DateTime.Now, Created = DateTime.Now, CreatedBy = ClientFactory.UserID }; new Client().Save(document, "Uploaded from Mobile Device"); File.Delete(file); } Thread.Sleep(1000); } }, _cancel.Token ); } } public static class DigitalFormDocumentFactory { private static IDigitalFormDocumentHandler? _handler; public static void Init(THandler handler) where THandler : IDigitalFormDocumentHandler { _handler = handler; } public static void Run() => _handler?.Run(); public static void Stop() => _handler?.Stop(); public static void LoadDocument(Guid id, Action callback) => _handler?.LoadDocument(id, callback); public static byte[]? LoadDocument(Guid id) => _handler?.LoadDocument(id); public static Guid SaveDocument(byte[] data) => _handler?.SaveDocument(data) ?? Guid.Empty; } }