private static async Task DesiredPropertyUpdateHandler(TwinCollection desiredProperties, object userContext)
        {
            var deviceClient = (DeviceClient)userContext;
            var dpJson       = desiredProperties.ToJson();

            AppStreamWriter.WriteLine($"Updated:{dpJson}");
        }
        private static async Task <MethodResponse> MethodHandler(MethodRequest methodRequest, object userContext)
        {
            AppStreamWriter.WriteLine($"Invoked:{methodRequest.Name}({methodRequest.DataAsJson})");
            var payload = new
            {
                message = "OK"
            };
            var response = new MethodResponse(System.Text.Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(payload)), 200);

            return(response);
        }
        private static async Task ReceiveMessageHandler(Message message, object userContext)
        {
            var recvMsg = new
            {
                properties = message.Properties,
                message    = System.Text.Encoding.UTF8.GetString(message.GetBytes())
            };

            AppStreamWriter.WriteLine($"Recieved:{Newtonsoft.Json.JsonConvert.SerializeObject(recvMsg)}");
            var deviceClient = (DeviceClient)userContext;
            await deviceClient.CompleteAsync(message);
        }
        /// <summary>
        /// <para>ExportFormat:</para>
        ///
        /// <para>VocabRound:int</para>
        /// <para>KanjiRound:int</para>
        ///
        /// <para>Lesson:id|name|type|size</para>
        ///
        /// <para>Word-1:id|kana|kanji|translation|description|type|eFactorTransl|lastRoundTransl|nextRoundTransl|eFactorJap|lastRoundJap|nextRoundJap|showFlags|timeStampTransl|timeStampJap</para>
        ///
        /// <para>Word-size:id|kana|kanji|translation|description|type|eFactorTransl|lastRoundTransl|nextRoundTransl|eFactorJap|lastRoundJap|nextRoundJap|showFlags|timeStampTransl|timeStampJap</para>
        ///
        /// <para>or</para>
        ///
        /// <para>Kanji-1:id|kanji|meaning|onyomi|kunyomi|example|strokeOrder|efactor|lastRound|nextRound|timestamp</para>
        /// <para>...</para>
        /// <para>Kanji-size:id|kanji|meaning|onyomi|kunyomi|example|strokeOrder|efactor|lastRound|nextRound|timestamp</para>
        ///
        /// <para>or</para>
        ///
        /// <para>Cloze-1:id|text|insertText|hintText</para>
        /// <para>...</para>
        /// <para>Cloze-size:id|text|insertText|hintText</para>
        ///
        /// <para>empty-line = end</para>
        /// </summary>
        public static String ExportToFile(Stream exportStream)
        {
            StringBuilder sb = new StringBuilder();

            using (AppStreamWriter sw = new AppStreamWriter(exportStream))
            {
                sw.WriteLine(AppSettings.VocabRound);
                sw.WriteLine(AppSettings.KanjiRound);

                int exportedLessons = 0;
                int exportedWords   = 0;
                int exportedClozes  = 0;
                int exportedKanjis  = 0;

                foreach (Lesson lesson in database.lessons)
                {
                    sw.WriteLine(lesson.ToExportString());

                    foreach (Word word in lesson.Words)
                    {
                        sw.WriteLine(word.ToExportString());
                    }

                    foreach (Cloze cloze in lesson.Clozes)
                    {
                        sw.WriteLine(cloze.ToExportString());
                    }

                    foreach (Kanji kanji in lesson.Kanjis)
                    {
                        sw.WriteLine(kanji.ToExportString());
                    }

                    exportedWords  += lesson.Words.Count;
                    exportedClozes += lesson.Clozes.Count;
                    exportedKanjis += lesson.Kanjis.Count;
                }
                exportedLessons = database.lessons.Count();

                sb.AppendLine("Datenbank erfolgreich gesichert!");
                sb.AppendLine("Lektionen\t: " + exportedLessons);
                sb.AppendLine("Wörter\t\t: " + exportedWords);
                sb.AppendLine("Lückentexte\t: " + exportedClozes);
                sb.AppendLine("Kanjis\t\t: " + exportedKanjis);
            }

            String exportResults = sb.ToString();

            sb.Clear();

            return(exportResults);
        }
        public static String ExportToFile(IRandomAccessStream exportStream)
        {
            StringBuilder exportResults = new StringBuilder();

            using (AppStreamWriter sw = new AppStreamWriter(exportStream.AsStream()))
            {
                LoadLessonsUnsorted();

                //write Number of Lessons
                sw.WriteLine(AppData.Lessons.Length.ToString());

                int exportedLessons = 0;
                int exportedWords = 0;
                int exportedSentences = 0;
                int exportedKanjis = 0;

                foreach (Lesson lesson in AppData.Lessons)
                {
                    sw.WriteLine(lesson.ToExportString());

                    switch (lesson.type)
                    {
                        case 0: exportedWords += WriteVocabLesson(sw, lesson); break;
                        case 1: exportedSentences += WriteInsertLesson(sw, lesson); break;
                        case 2: break;
                        case 3: exportedKanjis += WriteKanjiLesson(sw, lesson); break;
                        case 4: break;
                    }

                    ++exportedLessons;
                }

                exportResults.AppendLine("Datenbank erfolgreich exportiert!");
                exportResults.AppendLine("Exportierte Lektionen\t: " + exportedLessons);
                exportResults.AppendLine("Exportierte Wörter\t: " + exportedWords);
                exportResults.AppendLine("Exportierte Lückentexte\t: " + exportedSentences);
                exportResults.AppendLine("Exportierte Kanjis\t\t: " + exportedKanjis);
            }

            AppData.Lessons = null;
            AppData.Words = null;
            AppData.Sentences = null;
            AppData.Kanjis = null;

            return exportResults.ToString();
        }
        static async Task DoWork(string iothubCS)
        {
            DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(iothubCS);

            try
            {
                string deviceId = iothubCS.Split(";")[1].Split("=")[1];

                deviceClient.SetConnectionStatusChangesHandler(ConnectionStatusChangeHandler);
                await deviceClient.SetDesiredPropertyUpdateCallbackAsync(DesiredPropertyUpdateHandler, deviceClient);

                await deviceClient.SetMethodDefaultHandlerAsync(MethodHandler, deviceClient);

                await deviceClient.SetReceiveMessageHandlerAsync(ReceiveMessageHandler, deviceClient);

                await deviceClient.OpenAsync();

                var reported    = new TwinCollection();
                var targetProps = new
                {
                    target = TargetDeviceId
                };
                reported["configuration"] = new TwinCollection(Newtonsoft.Json.JsonConvert.SerializeObject(targetProps));
                await deviceClient.UpdateReportedPropertiesAsync(reported);

#if TEST
                int count = 10;
                for (int i = 0; i < count; i++)
                {
                    var msgContent = new
                    {
                        deviceId  = deviceId,
                        timestamp = DateTime.UtcNow,
                        count     = i
                    };
                    var msgJson = Newtonsoft.Json.JsonConvert.SerializeObject(msgContent);
                    var msg     = new Message(System.Text.Encoding.UTF8.GetBytes(msgJson));
                    await deviceClient.SendEventAsync(msg);

                    Console.WriteLine($"Send - {msgJson}");
                    await Task.Delay(5000);
                }
#endif
                while (true)
                {
                    var input = AppStreamReader.ReadLine().Trim();
                    if (input.ToLower().StartsWith("quit"))
                    {
                        AppStreamWriter.WriteLine("log:Quit");
                        break;
                    }
                    else
                    {
                        try
                        {
                            string d2cMessageKey = "d2c:";
                            string urpMessageKey = "urp:";
                            if (input.StartsWith(d2cMessageKey))
                            {
                                var msg = new Message(System.Text.Encoding.UTF8.GetBytes(input.Substring(d2cMessageKey.Length)));
                                AppStreamWriter.WriteLine($"log:Send D2C - {input}");
                                await deviceClient.SendEventAsync(msg);
                            }
                            else if (input.StartsWith(urpMessageKey))
                            {
                                AppStreamWriter.WriteLine($"log:Update RP - {input}");
                                reported["External"] = new TwinCollection(input.Substring(urpMessageKey.Length));
                                await deviceClient.UpdateReportedPropertiesAsync(reported);
                            }
                        }
                        catch (Exception ex)
                        {
                            AppStreamWriter.WriteLine($"error:Exeption - {ex.Message}");
                        }
                    }
                }


                await deviceClient.CloseAsync();
            }
            catch (Exception ex)
            {
                AppStreamWriter.WriteLine($"log:Exception {ex.Message}");
            }
        }
 private static void ConnectionStatusChangeHandler(ConnectionStatus status, ConnectionStatusChangeReason reason)
 {
     AppStreamWriter.WriteLine($"log:ConnectionStatus Changed - status={status},reason={reason}");
 }
        private static int WriteVocabLesson(AppStreamWriter sw, Lesson lesson)
        {
            LoadWords(lesson);

            foreach (Word word in AppData.Words)
            {
                sw.WriteLine(word.ToExportString());
            }

            return AppData.Words.Length;
        }
        private static int WriteKanjiLesson(AppStreamWriter sw, Lesson lesson)
        {
            LoadKanjis(lesson);

            foreach (Kanji kanji in AppData.Kanjis)
            {
                sw.WriteLine(kanji.ToExportString());
            }

            return AppData.Kanjis.Length;
        }
        private static int WriteInsertLesson(AppStreamWriter sw, Lesson lesson)
        {
            LoadSentences(lesson);

            foreach (Sentence sentence in AppData.Sentences)
            {
                sw.WriteLine(sentence.ToExportString());
            }

            return AppData.Sentences.Length;
        }