public HttpResponseMessage <string> CreateTicket([FromBody] ReadiDeskTicket data)
        {
            if (data == null)
            {
                return(new HttpResponseMessage <string>(HttpStatusCode.BadRequest));
            }

            var idString = ReadiDeskService.CreateTicket(data);

            return(new HttpResponseMessage <string>(idString, HttpStatusCode.OK));
        }
        public HttpResponseMessage <string> Feedback([FromBody] FeedbackData data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            var idString = Guid.NewGuid().ToString();

            var text = "";

            // Aggregate for some misguided reason throws if the collection is empty
            if (data.Messsages.Count > 0)
            {
                text = data.Messsages.Aggregate((a, p) => a + (string.IsNullOrEmpty(a) ? "" : "\r\n") + p);
            }

            var context = new RequestContextData(EDC.ReadiNow.IO.RequestContext.GetContext());

            if (context == null || context.Identity == null || context.Tenant == null)
            {
                throw new InvalidOperationException("Failed to determine identity");
            }

            string tenantName = context.Tenant.Name;
            string userName   = context.Identity.Name;

            var e = ReadiNow.Model.Entity.Get <UserAccount>(context.Identity.Id);

            if (e == null)
            {
                throw new InvalidOperationException("Failed to determine account holder");
            }

            string personName = e.AccountHolder != null ? e.AccountHolder.Name : context.Identity.Name;

            var path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);

            path = Path.Combine(path, @"ReadiNow\ClientLogs");
            //todo- factor out that clean routine... just can't remember a quick way in C#....
            path = Path.Combine(path, Regex.Replace(tenantName, @"[^A-Za-z0-9_]+", "-"));
            path = Path.Combine(path, Regex.Replace(userName, @"[^A-Za-z0-9_]+", "-"));
            path = Path.Combine(path, idString);

            Directory.CreateDirectory(path);
            Directory.CreateDirectory(Path.Combine(path, "attachments"));

            using (var fs = new FileStream(Path.Combine(path, "comments.txt"), FileMode.Create))
                using (var w = new StreamWriter(fs))
                {
                    w.Write(data.Comments);
                    w.Close();
                }

            using (var fs = new FileStream(Path.Combine(path, "browser.log"), FileMode.Create))
                using (var w = new StreamWriter(fs))
                {
                    w.Write(text);
                    w.Close();
                }

            if (data.Attachments != null) // am so over null checks.... foreach throws
            {
                foreach (var a in data.Attachments)
                {
                    // strip off things like data:text/plain;base64,
                    if (Regex.IsMatch(a.Data, "^data:.*;base64,"))
                    {
                        a.Data = a.Data.Substring(a.Data.IndexOf(',') + 1);
                    }

                    using (var fs = new FileStream(Path.Combine(path, "attachments", a.Name + "." + a.Ext), FileMode.Create))
                        using (var bw = new BinaryWriter(fs))
                        {
                            var content = Convert.FromBase64String(a.Data);
                            bw.Write(content);
                            bw.Close();
                        }
                }
            }

            SaveRecentServerLogs(path);

            ReadiNow.Diagnostics.EventLog.Application.WriteInformation("Client feedback saved to {0}", path);

            // if configured to create a ticket in ReadiDesk then do so

            var description = "";

            description += "email: " + data.Email + "\n";
            description += "phone: " + data.Phone + "\n";
            description += "tenant: " + tenantName + "\n";
            description += "account: " + userName + "\n";
            description += "user: "******"\n";
            description += "front end server: " + Dns.GetHostEntry("localhost").HostName + "\n";
            description += "platform version: " + SystemInfo.PlatformVersion + "\n";
            description += "branch name: " + SystemInfo.BranchName + "\n";

            var apps    = ReadiNow.Model.Entity.GetInstancesOfType <Solution>();
            var appList = apps.Aggregate("", (a, p) => a + (string.IsNullOrEmpty(a) ? "" : ", ") +
                                         p.Name + " (" + p.SolutionVersionString + ")");

            description += "apps: " + appList + "\n";

            description += "\ndetails: " + data.Comments + "\n\n";

            var ticket = new ReadiDeskTicket
            {
                TenantName  = tenantName,
                UserName    = userName,
                Summary     = data.Comments.Split('\n').FirstOrDefault(),
                Description = description,
                Attachments = new List <Attachment>()
                {
                    new Attachment {
                        Name = "consolelog", Ext = "txt", Data = Convert.ToBase64String(Encoding.UTF8.GetBytes(text))
                    }
                }
            };

            ticket.Summary = GetSanitizedNameFieldValue(ticket.Summary);    // ticket summary is saved as the name of the ticket
            if (data?.Attachments != null)
            {
                ticket.Attachments = ticket.Attachments.Concat(data.Attachments).ToList( );
            }
            idString = ReadiDeskService.RemoteCreateTicket(ticket) ?? idString;

            return(new HttpResponseMessage <string>(idString, HttpStatusCode.OK));
        }