/// <summary>
        ///     Get general information
        /// </summary>
        public void GetSpojInfo()
        {
            if (JobLocker.IsDownloadSpojInfoInProcess)
            {
                return;
            }

            JobLocker.IsDownloadSpojInfoInProcess = true;

            try
            {
                var text = "";

                using (var client = new SpojClient())
                {
                    var adminAccountTask = _adminSettingCacheBusiness.GetFullInfo();
                    adminAccountTask.Wait();

                    var rankUrl     = string.Format(_rankUrl, adminAccountTask.Result.ContestName);
                    var downloadUrl = string.Format(_downloadUrl, adminAccountTask.Result.ContestName);

                    var adminAccount = adminAccountTask.Result;
                    if (string.IsNullOrEmpty(adminAccount.Username) || string.IsNullOrEmpty(adminAccount.Password))
                    {
                        JobLocker.IsDownloadSpojInfoInProcess = false;
                        return;
                    }

                    var result = client.LoginAsync(adminAccount.Username, adminAccount.Password);
                    result.Wait();

                    text = client.GetText(rankUrl);
                    Thread.Sleep(1000);
                    text = client.GetText(downloadUrl);
                }

                var tokenizer = new SpojDataTokenizer(text);

                var contest = ParseContest(tokenizer);
                contest.ProblemsInfo = ParseProblems(tokenizer);
                contest.Users        = ParseUsers(tokenizer);

                ParseUserSubmissions(tokenizer, contest.Users, contest.ProblemsInfo);
            }
            catch (Exception e)
            {
                LogHepler.WriteSystemErrorLog(e, ApplicationConfigs.SystemInfo.ErrorLogFolderPath);
            }

            JobLocker.IsDownloadSpojInfoInProcess = false;
        }
        private SpojContestModel ParseContest(SpojDataTokenizer tokenizer)
        {
            var nLines  = tokenizer.GetInt();
            var contest = new SpojContestModel()
            {
                Start = tokenizer.GetUnixTime(),
                End   = tokenizer.GetUnixTime(),
            };

            tokenizer.Skip(1);
            contest.Name = tokenizer.GetNext();
            tokenizer.Skip(nLines - 4);
            return(contest);
        }
        private Dictionary <int, SpojUserModel> ParseUsers(SpojDataTokenizer tokenizer)
        {
            var users  = new Dictionary <int, SpojUserModel>();
            var nUsers = tokenizer.GetInt();
            var nLines = tokenizer.GetInt();

            var listChunk    = new List <SpojUserModel>();
            var listChunkIds = new List <int>();

            var chunkSteps = (int)Math.Ceiling((double)nUsers / _chunkSize);

            for (int i = 0; i < chunkSteps; i++)
            {
                for (int j = i * _chunkSize; j < (i + 1) * _chunkSize && j < nUsers; j++)
                {
                    var user = new SpojUserModel()
                    {
                        UserId      = tokenizer.GetInt(),
                        Username    = tokenizer.GetNext(),
                        DisplayName = tokenizer.GetNext(),
                        Email       = tokenizer.GetNext()
                    };
                    tokenizer.Skip(nLines - 4);
                    users[user.UserId] = user;

                    listChunk.Add(user);
                    listChunkIds.Add(user.UserId);
                }
                var ids         = listChunkIds;
                var listExist   = _accountRepository.Get(x => ids.Contains(x.SpojUserId)).Select(x => x.SpojUserId).ToList();
                var listEntites = listChunk.Where(x => !listExist.Contains(x.UserId)).Select(x => new AccountEntity
                {
                    SpojUserId  = x.UserId,
                    UserName    = x.Username,
                    DisplayName = x.DisplayName,
                    Email       = x.Email
                });

                _accountRepository.InsertRange(listEntites);
                _accountRepository.SaveChanges();

                listChunk    = new List <SpojUserModel>();
                listChunkIds = new List <int>();
            }

            return(users);
        }
        private void ParseUserSubmissions(SpojDataTokenizer tokenizer, Dictionary <int, SpojUserModel> users, Dictionary <int, SpojProblemInfoModel> problemsInfo)
        {
            var nSeries = tokenizer.GetInt();
            var nLine   = tokenizer.GetInt();

            tokenizer.Skip(1);
            var nSubmissions = tokenizer.GetInt();

            var listChunk    = new List <SpojSubmissionModel>();
            var listChunkIds = new List <int>();

            var chunkSteps = (int)Math.Ceiling((double)nSubmissions / _chunkSize);

            for (int i = 0; i < chunkSteps; i++)
            {
                for (int j = i * _chunkSize; j < (i + 1) * _chunkSize && j < nSubmissions; j++)
                {
                    var userId        = tokenizer.GetInt();
                    var spojProblemId = tokenizer.GetInt();
                    var time          = tokenizer.GetUnixTime();
                    var status        = tokenizer.GetInt();
                    var language      = tokenizer.GetInt();
                    var score         = tokenizer.GetFloat();
                    var runTime       = tokenizer.GetFloat();
                    tokenizer.Skip(1);
                    var id = tokenizer.GetInt();

                    var languageText = "";
                    switch (language)
                    {
                    case 10: languageText = "Java"; break;

                    case 27: languageText = "C#"; break;

                    case 32: languageText = "JS2"; break;

                    default: languageText = "Other Languages"; break;
                    }
                    tokenizer.Skip(nLine - 9);

                    if (!problemsInfo.ContainsKey(spojProblemId))
                    {
                        continue;
                    }
                    var problemInfo = problemsInfo[spojProblemId];

                    var submission = new SpojSubmissionModel
                    {
                        Id        = id,
                        Time      = time,
                        Score     = status == 15 && problemInfo.Type == 2 ? score : (status == 15 && problemInfo.Type == 0 ? 100 : 0),
                        RunTime   = runTime,
                        Language  = languageText,
                        UserId    = userId,
                        ProblemId = spojProblemId
                    };

                    listChunk.Add(submission);
                    listChunkIds.Add(submission.Id);

                    SpojUserModel user = null;
                    if (users.TryGetValue(userId, out user))
                    {
                        SpojProblemModel problem = null;
                        if (!user.Problems.TryGetValue(spojProblemId, out problem))
                        {
                            problem = new SpojProblemModel()
                            {
                                Id = spojProblemId, Code = problemInfo.Code
                            };
                            user.Problems[spojProblemId] = problem;
                        }
                        problem.Submissions.Add(submission);
                    }
                }

                var        ids             = listChunkIds;
                var        listIdsCache    = _submissionCacheBusiness.GetIds();
                List <int> listNonExisting = new List <int>();
                foreach (var id in listChunkIds)
                {
                    if (!listIdsCache.Contains(id))
                    {
                        listNonExisting.Add(id);
                    }
                }

                var listNotExist = listChunk.Where(x => listNonExisting.Contains(x.Id));

                var listEntities = (from item in listNotExist
                                    let internalProblemId = _problemRepository.Get(x => x.SpojId == item.ProblemId).Select(x => x.Id).FirstOrDefault()
                                                            let internalAccountId = _accountRepository.Get(x => x.SpojUserId == item.UserId).Select(x => x.Id).FirstOrDefault()
                                                                                    select new SubmissionEntity
                {
                    SpojId = item.Id,
                    SubmitTime = item.Time,
                    Score = item.Score,
                    RunTime = item.RunTime,
                    Language = item.Language,
                    ProblemId = internalProblemId == 0 ? (int?)null : internalProblemId,
                    AccountId = internalAccountId == 0 ? (int?)null : internalAccountId
                }).ToList();
                _submissionRepository.InsertRange(listEntities);
                _submissionRepository.SaveChanges();

                listChunk    = new List <SpojSubmissionModel>();
                listChunkIds = new List <int>();
                _submissionCacheBusiness.AddRangeIds(listNonExisting);
            }
        }
        private Dictionary <int, SpojProblemInfoModel> ParseProblems(SpojDataTokenizer tokenizer)
        {
            var prolems   = new Dictionary <int, SpojProblemInfoModel>();
            var nProblems = tokenizer.GetInt();
            var nLines    = tokenizer.GetInt();

            var listCheckingIds = new List <int>();

            var listChunk  = new List <SpojProblemInfoModel>();
            var chunkSteps = (int)Math.Ceiling((double)nProblems / _chunkSize);

            for (int i = 0; i < chunkSteps; i++)
            {
                for (int j = i * _chunkSize; j < (i + 1) * _chunkSize && j < nProblems; j++)
                {
                    var problemModel = new SpojProblemInfoModel()
                    {
                        Id         = tokenizer.GetInt(),
                        TimeLimit  = tokenizer.GetFloat(),
                        Code       = tokenizer.GetNext(),
                        Name       = tokenizer.GetNext(),
                        Type       = tokenizer.GetInt(),
                        ProblemSet = tokenizer.GetNext()
                    };

                    listChunk.Add(problemModel);
                    listCheckingIds.Add(problemModel.Id);

                    tokenizer.Skip(nLines - 6);
                    prolems[problemModel.Id] = problemModel;
                }

                var ids = listCheckingIds;

                var        listIdsCache    = _problemCacheBusiness.GetIds();
                List <int> listNonExisting = new List <int>();
                foreach (var id in listCheckingIds)
                {
                    if (!listIdsCache.Contains(id))
                    {
                        listNonExisting.Add(id);
                    }
                }

                var listEntitties = listChunk.Where(x => listNonExisting.Contains(x.Id)).Select(model => new ProblemEntity
                {
                    SpojId         = model.Id,
                    TimeLimit      = model.TimeLimit,
                    Code           = model.Code,
                    Name           = model.Name,
                    Type           = model.Type,
                    SpojProblemSet = model.ProblemSet
                })
                                    .ToList();

                _problemRepository.InsertRange(listEntitties);
                _problemRepository.SaveChanges();
                listChunk       = new List <SpojProblemInfoModel>();
                listCheckingIds = new List <int>();
                _problemCacheBusiness.AddRangeIds(listNonExisting);
            }
            _problemRepository.SaveChanges();


            return(prolems);
        }