//authenticate state
        public static string ReturnSelectedResponse(string tag, string argument, ref string state, string userSession, ref string userMailBox)
        {
            var math = Regex.Match(argument, "^(\"(?:[^\"]*)\"|(?:[^\\s]+))");

            // kiểm tra đối số lệnh select
            if (!math.Success)
            {
                return(Response.ReturnParseErrorResponse(tag, "SELECT"));
            }
            string mailbox = math.Groups[1].Value.Replace("\"", "");
            //truy xuất thông tin về mailbox từ ImapDB
            List <MailBoxInfo> mailBoxInfo = SqliteQuery.LoadMailBoxInfo(userSession, mailbox);

            //báo lỗi nếu mailbox không tồn tại
            if (mailBoxInfo.Count == 0)
            {
                return(tag + " NO Mailbox does not exist");
            }
            // thay đổi trạng thái sang selected state
            state = "selected";
            // gán usermailbox cho session
            userMailBox = mailbox;
            // gán thông tin trả về vào response
            string respose = "";

            respose += $"* {mailBoxInfo[0].mailexists} EXISTS\r\n";
            respose += $"* {mailBoxInfo[0].recent} RECENT\r\n";
            if (mailBoxInfo[0].firstunseen > 0)
            {
                respose += $"* OK [UNSEEN {mailBoxInfo[0].firstunseen}] Message {mailBoxInfo[0].firstunseen} is first unseen\r\n";
            }
            respose += $"* OK [UIDVALIDITY {mailBoxInfo[0].uidvalidity}] UIDs valid\r\n";
            respose += $"* OK [UIDNEXT {mailBoxInfo[0].uidnext}] Predicted next UID\r\n";
            respose += @"* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)" + "\r\n";
            respose += @"* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft)] " + "\r\n";
            respose += tag + " OK [READ-WRITE] SELECT completed";
            int success;

            if (mailBoxInfo[0].recent != 0)
            {
                success = SqliteQuery.UpdateRecentFlag(userSession, userMailBox);
            }
            return(respose);
        }
        public static string ReturnLsubResponse(string tag, string argument, string userSession)
        {
            string response = "";
            string root     = Environment.CurrentDirectory + $"\\ImapMailBox\\{userSession}\\";
            var    math     = Regex.Match(argument, "^(\"(?:[^\"]*)\"|(?:[^\\s]+)) (\"(?:[^\"]*)\"|(?:[^\\s]+))");

            if (!math.Success)
            {
                return(Response.ReturnParseErrorResponse(tag, "LSUB"));
            }
            // lấy reference từ group
            string reference = math.Groups[1].Value.Replace("\"", "");
            string dir       = root;

            if (Regex.IsMatch(reference, @"^(./)?.*"))
            {
                dir += reference.Replace("./", "");
            }
            // lấy mailboxName từ group
            string mailboxName = math.Groups[2].Value.Replace("\"", "");

            // reference = root và mailboxName =""
            if (dir == root && mailboxName == "")
            {
                return("* LSUB (\\Noselect ) \"/\" \"\"\r\n" + tag + " OK LSUB completed");
            }
            // kiểm tra đường dẫn
            // kiểm tra mailboxName bằng "*","%"
            if (!Directory.Exists(dir + mailboxName) && mailboxName != "*" && mailboxName != "%")
            {
                return(tag + " OK LSUB completed");
            }
            int temp = 0;

            if (mailboxName == "%")
            {
                temp        = 1;
                mailboxName = "*";
            }


            string[] dirList = Directory.GetDirectories(dir, mailboxName);
            foreach (string mailboxDir in dirList)
            {
                // nếu mailboxName bằng "%" kiểm tra folder không có subfolder
                if (temp == 1 && Directory.GetDirectories(mailboxDir).Length != 0)
                {
                    continue;
                }
                string             mailbox         = mailboxDir.Replace(root, "");
                List <MailBoxInfo> ListmailBoxInfo = SqliteQuery.LoadMailBoxInfo(userSession, mailbox);
                if (ListmailBoxInfo.Count == 0)
                {
                    return(tag + " OK LSUB completed");
                }
                MailBoxInfo mailBoxInfo = ListmailBoxInfo[0];
                // kiểm tra mailbox đã được subcribe chưa
                if (mailBoxInfo.subscribed == 0)
                {
                    continue;
                }
                // tạo response
                string[] tempArr =
                {
                    (mailBoxInfo.all == 1?"\\All":""),
                    (mailBoxInfo.archive == 1?"\\Archive":""),
                    (mailBoxInfo.drafts == 1?"\\Drafts":""),
                    (mailBoxInfo.flagged == 1?"\\Flagged":""),
                    (mailBoxInfo.inbox == 1?"\\Inbox":""),
                    (mailBoxInfo.junk == 1?"\\Junk":""),
                    (mailBoxInfo.marked == 1?"\\Marked":"UnMarked"),
                    (mailBoxInfo.nointeriors == 1?"\\NoInferiors":""),
                    (mailBoxInfo.noselect == 1?"\\Noselect":""),
                    (mailBoxInfo.sent == 1?"\\Sent":""),
                    (mailBoxInfo.trash == 1?"\\Trash":"")
                };
                tempArr   = tempArr.Where(x => !string.IsNullOrEmpty(x)).ToArray();
                response += "* LSUB (" + string.Join(' ', tempArr) + $") \"/\" \"{reference}{mailbox}\"\r\n";
            }
            return(response + tag + " OK LSUB completed");
        }
        public static string ReturnExpungeResponse(string tag, string userSession, string userMailBox, bool fromUIDCommand = false, string argument = "")
        {
            List <MailInfo> mailInfoList = new List <MailInfo>();

            if (argument != "")
            {
                var math = Regex.Match(argument, @"^((?:(?:(?:[1-9]+|\*):(?:[1-9]+|\*)|[1-9]+),)*(?:(?:[1-9]+|\*):(?:[1-9]+|\*)|[1-9]+))");
                if (!math.Success)
                {
                    return(ReturnParseErrorResponse(tag, "FETCH"));
                }
                List <MailInfo> tempMailInfoList;
                string          right        = "";
                string          left         = "";
                string[]        mailIndexArr = math.Groups[1].Value.Split(',');
                foreach (string mailIndex in mailIndexArr)
                {
                    if (mailIndex.Contains(':'))
                    {
                        string[] temp = mailIndex.Split(':', StringSplitOptions.RemoveEmptyEntries);
                        if (temp[0] == "*")
                        {
                            if (fromUIDCommand)
                            {
                                left = "uid";
                            }
                            else
                            {
                                left = "numrow";
                            }
                        }
                        else
                        {
                            left = temp[0];
                        }
                        if (temp[1] == "*")
                        {
                            if (fromUIDCommand)
                            {
                                right = "uid";
                            }
                            else
                            {
                                right = "numrow";
                            }
                        }
                        else
                        {
                            right = temp[1];
                        }
                        if (fromUIDCommand)
                        {
                            tempMailInfoList = SqliteQuery.LoadMailInfoWithUID(userSession, userMailBox, left, right);
                        }
                        else
                        {
                            tempMailInfoList = SqliteQuery.LoadMailInfoWithIndex(userSession, userMailBox, left, right);
                        }
                    }
                    else
                    {
                        if (fromUIDCommand)
                        {
                            tempMailInfoList = SqliteQuery.LoadMailInfoWithUID(userSession, userMailBox, mailIndex);
                        }
                        else
                        {
                            tempMailInfoList = SqliteQuery.LoadMailInfoWithIndex(userSession, userMailBox, mailIndex);
                        }
                    }
                    foreach (MailInfo tempMail in tempMailInfoList)
                    {
                        if (!mailInfoList.Contains(tempMail) && tempMail.deleted == 1)
                        {
                            mailInfoList.Add(tempMail);
                        }
                    }
                }
                mailInfoList.Sort((x, y) => x.uid.CompareTo(y.uid));
            }
            else
            {
                mailInfoList = SqliteQuery.LoadDeletedMail(userSession, userMailBox);
            }
            if (mailInfoList.Count == 0)
            {
                return(tag + " OK EXPUNGE completed");
            }
            List <string> TrashMailbox = SqliteQuery.LoadTrashMailBoxName(userSession);
            string        response     = "";
            int           success;
            string        soursePath;
            string        desPath;
            long          baseUID;
            string        root = Environment.CurrentDirectory + $"/ImapMailBox/{userSession}";

            if (TrashMailbox.IndexOf(userMailBox) == -1 && TrashMailbox.Count != 0)
            {
                foreach (string mailBox in TrashMailbox)
                {
                    List <MailBoxInfo> mailBoxInfo = SqliteQuery.LoadMailBoxInfo(userSession, mailBox);
                    if (mailBoxInfo.Count == 0)
                    {
                        return("OK EXPUNGE completed");
                    }
                    baseUID = mailBoxInfo[0].uidnext;
                    foreach (MailInfo mail in mailInfoList)
                    {
                        soursePath = root + $"/{userMailBox}/email_{baseUID}";
                        if (File.Exists(soursePath + ".msg"))
                        {
                            soursePath += ".msg";
                            desPath     = root + $"/{mailBox}/email_{baseUID}.msg";
                        }
                        else
                        {
                            if (File.Exists(soursePath + ".eml"))
                            {
                                soursePath += ".eml";
                                desPath     = root + $"/{mailBox}/email_{baseUID}.eml";
                            }
                            else
                            {
                                return(tag + "OK EXPUNGE completed");
                            }
                        }
                        File.Copy(soursePath, desPath);
                        File.Delete(soursePath);
                        success          = SqliteQuery.DeleteMailWithUID(userSession, userMailBox, mail.uid);
                        mail.uid         = baseUID++;
                        mail.mailboxname = mailBox;
                        success          = SqliteQuery.InsertMailIntoMailBox(userSession, mailBox, mail);
                        response        += $"* {mail.numrow} EXPUNGE\r\n";
                    }
                }
            }
            else
            {
                foreach (MailInfo mail in mailInfoList)
                {
                    soursePath = root + $"/{userMailBox}/email_{mail.uid}";
                    if (File.Exists(soursePath + ".msg"))
                    {
                        soursePath += ".msg";
                    }
                    else
                    {
                        if (File.Exists(soursePath + ".eml"))
                        {
                            soursePath += ".eml";
                        }
                        else
                        {
                            return(tag + "OK EXPUNGE completed");
                        }
                    }
                    File.Delete(soursePath);
                    success   = SqliteQuery.DeleteMailWithUID(userSession, userMailBox, mail.uid);
                    response += $"* {mail.numrow} EXPUNGE\r\n";
                }
            }
            response += tag + " OK EXPUNGE completed";
            return(response);
        }
        public static string ReturnAppendResponse(string tag, string argument, string userSession, AppendCall appendCall)
        {
            //var maths = Regex.Match(argument, "");
            var math = Regex.Match(argument, "^(?:((?:\"[\\w\\s]+\"|\\w+) \\((?:\\\\\\w+)*\\) \"[^\"]*\" \\{\\d*\\})|((?:\"[\\w\\s]+\"|\\w+) \\((?:\\\\\\w+)*\\) \\{\\d*\\})|((?:\"[\\w\\s]+\"|\\w+) \\{\\d*\\}))");

            if (!math.Success)
            {
                return(Response.ReturnParseErrorResponse(tag, "APPEND"));
            }
            MailInfo      mailAppend = new MailInfo();
            Flags         flags      = new Flags();
            string        mailBoxName;
            List <string> strFlag     = new List <string>();
            DateTime      Date        = DateTime.Now;
            int           messageSize = 0;

            if (math.Groups[3].Success)
            {
                math        = Regex.Match(math.Groups[3].Value, "(?:(\"[\\w\\s]+\"|\\w+) \\{(\\d*)\\})");
                mailBoxName = math.Groups[1].Value.Replace("\"", "");
                if (math.Groups[2].Value != "" && !Int32.TryParse(math.Groups[3].Value, out messageSize))
                {
                    return(Response.ReturnParseErrorResponse(tag, "APPEND"));
                }
            }
            else
            {
                if (math.Groups[2].Success)
                {
                    math        = Regex.Match(math.Groups[2].Value, "(?:(\"[\\w\\s]+\"|\\w+) \\(((?:\\\\\\w+)*)\\) \\{(\\d*)\\})");
                    mailBoxName = math.Groups[1].Value.Replace("\"", "");
                    if (math.Groups[2].Value != "")
                    {
                        strFlag = math.Groups[2].Value.Split(' ').ToList();
                    }
                    if (math.Groups[3].Value != "" && !Int32.TryParse(math.Groups[3].Value, out messageSize))
                    {
                        return(Response.ReturnParseErrorResponse(tag, "APPEND"));
                    }
                }
                else
                {
                    math        = Regex.Match(math.Groups[1].Value, "(?:(\"[\\w\\s]+\"|\\w+) \\(((?:\\\\\\w+)*)\\) \"([^\"]*)\" \\{(\\d*)\\})");
                    mailBoxName = math.Groups[1].Value.Replace("\"", "");
                    if (math.Groups[2].Value != "")
                    {
                        strFlag = math.Groups[2].Value.Split(' ').ToList();
                    }
                    if (math.Groups[3].Value != "")
                    {
                        try
                        {
                            Date = Convert.ToDateTime(math.Groups[3].Value);
                        }
                        catch
                        {
                            return(Response.ReturnParseErrorResponse(tag, "APPEND"));
                        }
                    }
                    if (math.Groups[4].Value != "" && !Int32.TryParse(math.Groups[4].Value, out messageSize))
                    {
                        return(Response.ReturnParseErrorResponse(tag, "APPEND"));
                    }
                }
            }
            List <MailBoxInfo> mailBoxInfoList = SqliteQuery.LoadMailBoxInfo(userSession, mailBoxName);

            if (mailBoxInfoList.Count == 0)
            {
                return(tag + " NO Mailbox does not exist");
            }
            if (!flags.BuildFlagItem(strFlag.ToArray()))
            {
                return(Response.ReturnParseErrorResponse(tag, "APPEND"));
            }
            mailAppend.user        = userSession;
            mailAppend.mailboxname = mailBoxName;
            mailAppend.uid         = mailBoxInfoList[0].uidnext;
            mailAppend.recent      = 1;
            mailAppend.seen        = (flags.seen == "1" ? 1 : 0);
            mailAppend.answered    = (flags.answered == "1" ? 1 : 0);
            mailAppend.deleted     = (flags.deleted == "1" ? 1 : 0);
            mailAppend.draft       = (flags.draft == "1" ? 1 : 0);
            mailAppend.flagged     = (flags.flagged == "1" ? 1 : 0);
            mailAppend.intertime   = ((DateTimeOffset)Date).ToUnixTimeSeconds();
            appendCall.isCall      = true;
            appendCall.mailInfo    = mailAppend;
            appendCall.size        = messageSize;
            appendCall.tag         = tag;
            return("+ Ready for append literal");
        }