internal UserUploadInfo GetUserUploadInfo(ClientData clientData, string imsi)
        {
            UserUploadInfo ret = new UserUploadInfo();

            #region Activity
            if (clientData.Activities != null)
            {
                ret.ActivityInfos = new List<AndroidUserAppActivityInfo>();
                foreach (var a in clientData.Activities)
                {
                    if (!string.IsNullOrEmpty(a.TimesPerHour))
                    {
                        var timesPerHour = a.TimesPerHour.Split(ASCII.VERTICAL_BAR_CHAR);
                        if (timesPerHour.Length >= 24)
                        {
                            ret.ActivityInfos.Add(new AndroidUserAppActivityInfo
                            {
                                IMSI = imsi,
                                PackageName = a.PackageName,
                                One = timesPerHour[0].ToInt32(),
                                Two = timesPerHour[1].ToInt32(),
                                Three = timesPerHour[2].ToInt32(),
                                Four = timesPerHour[3].ToInt32(),
                                Five = timesPerHour[4].ToInt32(),
                                Six = timesPerHour[5].ToInt32(),
                                Seven = timesPerHour[6].ToInt32(),
                                Eight = timesPerHour[7].ToInt32(),
                                Nine = timesPerHour[8].ToInt32(),
                                Ten = timesPerHour[9].ToInt32(),
                                Eleven = timesPerHour[10].ToInt32(),
                                Twelve = timesPerHour[11].ToInt32(),
                                Thirteen = timesPerHour[12].ToInt32(),
                                Fourteen = timesPerHour[13].ToInt32(),
                                Fifteen = timesPerHour[14].ToInt32(),
                                Sixteen = timesPerHour[15].ToInt32(),
                                SevenTeen = timesPerHour[16].ToInt32(),
                                Eighteen = timesPerHour[17].ToInt32(),
                                Nineteen = timesPerHour[18].ToInt32(),
                                Twenty = timesPerHour[19].ToInt32(),
                                TwentyOne = timesPerHour[20].ToInt32(),
                                TwentyTwo = timesPerHour[21].ToInt32(),
                                TwentyThree = timesPerHour[22].ToInt32(),
                                TwentyFour = timesPerHour[23].ToInt32(),
                                FromDate = clientData.From,
                                ToDate = clientData.To
                            });
                        }
                    }
                }
            }
            #endregion

            #region App Info
            if (clientData.Apps != null)
            {
                ret.AppInfos = new List<AndroidUserAppInfoOp>();
                foreach (var a in clientData.Apps)
                {
                    ret.AppInfos.Add(new AndroidUserAppInfoOp
                    {
                        IsAdd = a.Action == 0,
                        AndroidUserAppInfo = new AndroidUserAppInfo {
                            IMSI = imsi,
                            PackageName = a.PackageName,
                            VersionCode = a.VersionCode,
                            VersionName = a.VersionName,
                            MD5 = a.MD5,
                        }
                    });
                }
            }
            #endregion

            #region Traffic
            if (clientData.Traffics != null)
            {
                ret.AppTrafficInfos = new List<AndroidUserAppTrafficInfo>();
                foreach (var a in clientData.Traffics)
                {
                    ret.AppTrafficInfos.Add(new AndroidUserAppTrafficInfo {
                        IMSI = imsi,
                        PackageName = a.PackageName,
                        Traffic = a.Traffic,
                        FromDate = clientData.From,
                        ToDate = clientData.To
                    });
                }
            }
            #endregion

            return ret;
        }
        public void integration_test_for_user_upload_info()
        {
            var namevalues = new NameValueCollection();
            namevalues[MobileParam.Key_IMSI] = TEST_IMSI;
            _requestRepoMock.Setup<NameValueCollection>(m => m.Header).Returns(namevalues);
            MobileParam mobileParam = new MobileParam(requestRepo);

            var realRedisService = new RedisService();
            var realRedisLogger = new RedisLogger();
            realRedisService.FlushAll();
            realRedisLogger.Flush();

            UserInteractService userInteractService = new UserInteractService(realRedisLogger, realRedisService, new UserInteractUIService(realRedisService));
            //first time , add
            UserUploadInfo userUploadInfo = new UserUploadInfo
            {
                ActivityInfos = GetAndroidUserAppActivityInfos(),
                AppInfos = GetAppInfos(),
                AppTrafficInfos = GetAppTrafficInfos()
            };
            userInteractService.SaveUserUploadInfos(mobileParam, userUploadInfo);
            //second time , update
            namevalues = new NameValueCollection();
            namevalues[MobileParam.Key_IMSI] = TEST_IMSI;
            namevalues[MobileParam.Key_IsTouch] = "1";
            _requestRepoMock.Setup<NameValueCollection>(m => m.Header).Returns(namevalues);
            mobileParam = new MobileParam(requestRepo);

            userInteractService.SaveUserUploadInfos(mobileParam, userUploadInfo);

            Assert.NotNull(realRedisService.GetValueFromHash<string>("U:9460002850533220", "com.packagename.app1"));
            using (var redis = RedisClientManager.GetReadOnlyClient())
            {
                Assert.Equal(2, redis.GetListCount("Queue:AndroidUserUploadInfo:Logger"));
                var secondAndroidUserUploadInfo = JsonConvert.DeserializeObject<LogModel>(redis.GetItemFromList("Queue:AndroidUserUploadInfo:Logger", 1));
                Assert.Equal(LogOperationType.Update, secondAndroidUserUploadInfo.Operation);
                Assert.Equal(6, redis.GetListCount("Queue:AndroidUserAppInfo:Logger"));
                Assert.Equal(4, redis.GetListCount("Queue:AndroidUserAppTrafficInfo:AndroidUserAppTrafficInfoLogger"));
                Assert.Equal(4, redis.GetListCount("Queue:AndroidUserAppActivityInfo:AndroidUserAppActivityInfoLogger"));
            }
        }
        internal void SaveUserUploadInfos(MobileParam mobileParams, UserUploadInfo userUploadInfo)
        {
            var androidUserUploadInfo = EntityMapping.Auto<MobileParam, AndroidUserUploadInfo>(mobileParams);

            var operationType = LogOperationType.Add;
            if (RedisService.IsExist(GetIMSIKey(androidUserUploadInfo.Id)))
            {
                operationType = LogOperationType.Update;
            }

            LogService.AddLogModel(androidUserUploadInfo, operationType.ToString());

            if (userUploadInfo.AppInfos != null)
            {
                foreach (var appInfo in userUploadInfo.AppInfos)
                {
                    appInfo.AndroidUserAppInfo.Id = (appInfo.AndroidUserAppInfo.IMSI + appInfo.AndroidUserAppInfo.PackageName).SHA1Hash();
                    if (string.IsNullOrEmpty(appInfo.AndroidUserAppInfo.PackageName))
                    {
                        continue;
                    }
                    if (appInfo.IsAdd)
                    {
                        RedisService.SetEntryInHash<string>(GetIMSIKey(appInfo.AndroidUserAppInfo.IMSI), appInfo.AndroidUserAppInfo.PackageName, appInfo.AndroidUserAppInfo.VersionCode == null ? string.Empty : appInfo.AndroidUserAppInfo.VersionCode);
                    }
                    else
                    {
                        RedisService.DeleteEntryFromHash(GetIMSIKey(appInfo.AndroidUserAppInfo.IMSI), appInfo.AndroidUserAppInfo.PackageName);
                    }
                    operationType = appInfo.IsAdd ? LogOperationType.Add : LogOperationType.Delete;
                    LogService.AddLogModel(appInfo.AndroidUserAppInfo, operationType.ToString());
                }
            }

            if (userUploadInfo.AppTrafficInfos != null)
            {
                foreach (var appTrafficInfo in userUploadInfo.AppTrafficInfos)
                {
                    appTrafficInfo.Id = appTrafficInfo.ToString().SHA1Hash();
                    LogService.Add<AndroidUserAppTrafficInfo>(appTrafficInfo);
                }
            }

            if (userUploadInfo.ActivityInfos != null)
            {
                foreach (var activityInfo in userUploadInfo.ActivityInfos)
                {
                    activityInfo.Id = activityInfo.ToString().SHA1Hash();
                    LogService.Add<AndroidUserAppActivityInfo>(activityInfo);
                }

            }
        }