package com.hc.web;

import com.hc.business.mapper.UserVideoPositionMapper;
import com.hc.business.model.CourseChapterVideo;
import com.hc.business.model.UserCourse;
import com.hc.business.model.UserVideoPosition;
import com.hc.business.service.CourseChapterVideoService;
import com.hc.business.service.UserCourseService;
import com.hc.business.service.UserVideoPositionService;
import com.hc.core.utils.redis.RedisUtil;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.Map;

@SpringBootTest
class UserPositionServiceTests {


    @Autowired
    RedisUtil redisUtil;

    @Autowired
    UserVideoPositionService userVideoPositionService;

    @Autowired
    UserVideoPositionMapper mapper;

    @Autowired
    CourseChapterVideoService videoService;

    @Autowired
    UserCourseService userCourseService;

    private static final String REDIS_KEY_PREFIX = "user:video:position:";

    private UserVideoPosition new_position(){

        UserVideoPosition userVideoPosition = new UserVideoPosition();
        userVideoPosition.setVideoId(1);
        userVideoPosition.setUserId(100);
        userVideoPosition.setVideoPosition("20");
        userVideoPosition.setVideoTime("100.1");
        return  userVideoPosition;
    }


    private void clean_redis(UserVideoPosition userVideoPosition){

        //初始化清理掉缓存
        String key = REDIS_KEY_PREFIX + userVideoPosition.getUserId() + ":" + 1;
        if(redisUtil.hasKey(key)){
            redisUtil.del(key);
        }
    }
    /**
     * 测试根据课程id获取所有子目录id列表,测试访问数据库取值
     * 测试缓存中得数值
     */

    @Test
    void insert_new_video_position(){

        UserVideoPosition userVideoPosition = new_position();
        clean_redis(userVideoPosition);
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);

        String key = REDIS_KEY_PREFIX + userVideoPosition.getUserId() + ":" + 1;
        String key_v = "position" + String.valueOf(userVideoPosition.getVideoId());
        String key_t =  "videotime"+ String.valueOf(userVideoPosition.getVideoId());

        //验证redis
        Object position = redisUtil.hashGet(key,key_v);
        assert ((null != position) && (true == position.toString().equals("20")));
        Object time = redisUtil.hashGet(key,key_t);
        assert ((null != time) && (true == time.toString().equals("100.1")));


        //正常观看进度
        userVideoPosition.setVideoPosition("22");
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);
        position = redisUtil.hashGet(key,key_v);
        assert ((null != position) && (true == position.toString().equals("22")));
        time = redisUtil.hashGet(key,key_t);
        assert ((null != time) && (true == time.toString().equals("100.1")));

    }


    /**
     * 非正常播放一个视频
     */

    @Test
    void play_video_invalid_position(){
        UserVideoPosition userVideoPosition = new_position();
        clean_redis(userVideoPosition);
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);

        String key = REDIS_KEY_PREFIX + userVideoPosition.getUserId() + ":" + 1;
        String key_v = "position" + String.valueOf(userVideoPosition.getVideoId());
        String key_t =  "videotime"+ String.valueOf(userVideoPosition.getVideoId());

        //验证redis
        Object position = redisUtil.hashGet(key,key_v);
        assert ((null != position) && (true == position.toString().equals("20")));
        Object time = redisUtil.hashGet(key,key_t);
        assert ((null != time) && (true == time.toString().equals("100.1")));

        //正常观看进度
        userVideoPosition.setVideoPosition("22");
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);

        //错误观看进度，前台时间戳有问题
        userVideoPosition.setVideoPosition("19");
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);
        position = redisUtil.hashGet(key,key_v);
        assert ((null != position) && (true == position.toString().equals("22")));
        time = redisUtil.hashGet(key,key_t);
        assert ((null != time) && (true == time.toString().equals("100.1")));
    }

    @Test
    void play_video_invalid_video_time(){
        UserVideoPosition userVideoPosition = new_position();
        clean_redis(userVideoPosition);
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);

        String key = REDIS_KEY_PREFIX + userVideoPosition.getUserId() + ":" + 1;
        String key_v = "position" + String.valueOf(userVideoPosition.getVideoId());
        String key_t =  "videotime"+ String.valueOf(userVideoPosition.getVideoId());

        //验证redis
        Object position = redisUtil.hashGet(key,key_v);
        assert ((null != position) && (true == position.toString().equals("20")));
        Object time = redisUtil.hashGet(key,key_t);
        assert ((null != time) && (true == time.toString().equals("100.1")));

        //观看进度不正确，超过最大视频长度
        userVideoPosition.setVideoPosition("101");
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);
        position = redisUtil.hashGet(key,key_v);
        time = redisUtil.hashGet(key,key_t);
        assert ((null != position) && (position.toString().equals("100.1")) && (null != time) && (time.toString().equals("100.1")));
    }

    /*
    测试获取观看进度
     */

    @Test
    void get_video_position(){

        UserVideoPosition userVideoPosition = new_position();
        clean_redis(userVideoPosition);
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);

        String key = REDIS_KEY_PREFIX + userVideoPosition.getUserId() + ":" + 1;
        String key_v = "position" + String.valueOf(userVideoPosition.getVideoId());
        String key_t =  "videotime"+ String.valueOf(userVideoPosition.getVideoId());

        //验证redis
        Object position = redisUtil.hashGet(key,key_v);
        assert ((null != position) && (true == position.toString().equals("20")));
        Object time = redisUtil.hashGet(key,key_t);
        assert ((null != time) && (true == time.toString().equals("100.1")));

        //正常观看进度
        userVideoPosition.setVideoPosition("22");
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);
        Map<String,String> map = userVideoPositionService.findVideoPosition(userVideoPosition.getUserId(),userVideoPosition.getVideoId(),7,100);
        assert ((null != map) && (true == map.containsKey("position")) && (true == map.containsKey("videotime")));
        assert ((map.get("position").toString().equals("22")) && (map.get("videotime").toString().equals("100.1")));
    }

    /*
   获取一条不存在得观看记录
     */

    @Test
    void get_invalid_video_position(){

        UserVideoPosition userVideoPosition = new_position();
        clean_redis(userVideoPosition);
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);

        String key = REDIS_KEY_PREFIX + userVideoPosition.getUserId() + ":" + 1;
        String key_v = "position" + String.valueOf(userVideoPosition.getVideoId());
        String key_t =  "videotime"+ String.valueOf(userVideoPosition.getVideoId());

        //验证redis
        Object position = redisUtil.hashGet(key,key_v);
        assert ((null != position) && (true == position.toString().equals("20")));
        Object time = redisUtil.hashGet(key,key_t);
        assert ((null != time) && (true == time.toString().equals("100.1")));

        //获取一个不存在得观看记录
        Map<String,String> map = userVideoPositionService.findVideoPosition(userVideoPosition.getUserId(),5555,7,100);
        assert (null != map);
        assert ((null == map.get("position")) && (null == map.get("videotime")));
    }

    /*
    测试视频进度更新表记位
     */

    @Test
    void test_video_position_update_flag(){
        UserVideoPosition userVideoPosition = new_position();
        clean_redis(userVideoPosition);
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);

        String key = REDIS_KEY_PREFIX + userVideoPosition.getUserId() + ":" + 1;
        String key_v = "position" + String.valueOf(userVideoPosition.getVideoId());
        String key_t =  "videotime"+ String.valueOf(userVideoPosition.getVideoId());
        String key_u = "update"+String.valueOf(userVideoPosition.getVideoId());

        //验证redis
        Object position = redisUtil.hashGet(key,key_v);
        assert ((null != position) && (true == position.toString().equals("20")));
        Object time = redisUtil.hashGet(key,key_t);
        assert ((null != time) && (true == time.toString().equals("100.1")));
        Object update = redisUtil.hashGet(key,key_u);
        assert ((null != update) && (update.toString().equals("1")));

        //删除标记为，更新视频观看进度，改标记为需要重新标记
        redisUtil.hashDel(key,key_u);
        update = redisUtil.hashGet(key,key_u);
        assert (null == update);

//        正常观看进度
        userVideoPosition.setVideoPosition("22");
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);
        update = redisUtil.hashGet(key,key_u);
        assert ((null != update) && (update.toString().equals("1")));
    }

    /*
    测试刷新观看记录从缓存到数据库,新增
     */

    @Test
    void test_flush_position_todb_new(){
        UserVideoPosition userVideoPosition = new_position();
        clean_redis(userVideoPosition);
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);

        String key = REDIS_KEY_PREFIX + userVideoPosition.getUserId() + ":" + 1;
        String key_v = "position" + String.valueOf(userVideoPosition.getVideoId());
        String key_t =  "videotime"+ String.valueOf(userVideoPosition.getVideoId());

        //验证redis
        Object position = redisUtil.hashGet(key,key_v);
        assert ((null != position) && (true == position.toString().equals("20")));
        Object time = redisUtil.hashGet(key,key_t);
        assert ((null != time) && (true == time.toString().equals("100.1")));

        //清理数据库
        List<UserVideoPosition> list = mapper.selectUserPositionByUserAndVideo(userVideoPosition.getVideoId(),userVideoPosition.getUserId());
        if((null != list) && (list.size() > 0)){
            mapper.delete(list.get(0));
        }

        //刷新到数据库
        userVideoPositionService.flushToDb(userVideoPosition.getUserId(),userVideoPosition.getVideoId(),7,"2020",100);
        list = mapper.selectUserPositionByUserAndVideo(userVideoPosition.getVideoId(),userVideoPosition.getUserId());
        assert (list.size() == 1);
        UserVideoPosition uposition = list.get(0);
        assert (uposition.getVideoPosition().equals(userVideoPosition.getVideoPosition()));

    }

    /*
    测试刷新观看记录从缓存到数据库,更新
     */

    @Test
    void test_flush_position_todb_update(){
        UserVideoPosition userVideoPosition = new_position();
        clean_redis(userVideoPosition);
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);

        String key = REDIS_KEY_PREFIX + userVideoPosition.getUserId() + ":" + 1;
        String key_v = "position" + String.valueOf(userVideoPosition.getVideoId());
        String key_t =  "videotime"+ String.valueOf(userVideoPosition.getVideoId());

        //验证redis
        Object position = redisUtil.hashGet(key,key_v);
        assert ((null != position) && (true == position.toString().equals("20")));
        Object time = redisUtil.hashGet(key,key_t);
        assert ((null != time) && (true == time.toString().equals("100.1")));

        //清理数据库
        List<UserVideoPosition> list = mapper.selectUserPositionByUserAndVideo(userVideoPosition.getVideoId(),userVideoPosition.getUserId());
        if((null != list) && (list.size()>0)){
            mapper.delete(list.get(0));
        }

        //刷新到数据库
        userVideoPositionService.flushToDb(userVideoPosition.getUserId(),userVideoPosition.getVideoId(),7,"2020",100);
        list = mapper.selectUserPositionByUserAndVideo(userVideoPosition.getVideoId(),userVideoPosition.getUserId());
        assert (list.size() == 1);
        assert (list.get(0).getVideoPosition().equals("20"));

        ///跟新数据库观看记录
        userVideoPosition.setVideoPosition("40");
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);
        userVideoPositionService.flushToDb(userVideoPosition.getUserId(),userVideoPosition.getVideoId(),7,"2020",100);
        list = mapper.selectUserPositionByUserAndVideo(userVideoPosition.getVideoId(),userVideoPosition.getUserId());
        assert (list.size() == 1);
        assert (list.get(0).getVideoPosition().equals("40"));
    }


    /*
测试刷新观看记录从缓存到数据库,测试观看结标记
 */

    @Test
    void test_flush_position_todb_end(){
        UserVideoPosition userVideoPosition = new_position();
        clean_redis(userVideoPosition);
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);

        String key = REDIS_KEY_PREFIX + userVideoPosition.getUserId() + ":" + 1;
        String key_v = "position" + String.valueOf(userVideoPosition.getVideoId());
        String key_t =  "videotime"+ String.valueOf(userVideoPosition.getVideoId());

        //验证redis
        Object position = redisUtil.hashGet(key,key_v);


        assert ((null != position) && (true == position.toString().equals("20")));
        Object time = redisUtil.hashGet(key,key_t);
        assert ((null != time) && (true == time.toString().equals("100.1")));


        //清理数据库
        List<UserVideoPosition> list = mapper.selectUserPositionByUserAndVideo(userVideoPosition.getVideoId(),userVideoPosition.getUserId());
        //assert (list.size() == 0);
        if(null != list){
            mapper.delete(list.get(0));
        }

        //刷新到数据库
        userVideoPositionService.flushToDb(userVideoPosition.getUserId(),userVideoPosition.getVideoId(),7,"2020",100);
        list = mapper.selectUserPositionByUserAndVideo(userVideoPosition.getVideoId(),userVideoPosition.getUserId());
        assert (list.size() == 1);
        assert (list.get(0).getVideoPosition().equals("20"));

        ///跟新数据库观看记录
        userVideoPosition.setVideoPosition("96");
        userVideoPositionService.insertPositionToRedis(userVideoPosition,7);
        userVideoPositionService.flushToDb(userVideoPosition.getUserId(),userVideoPosition.getVideoId(),7,"2020",100);
        list = mapper.selectUserPositionByUserAndVideo(userVideoPosition.getVideoId(),userVideoPosition.getUserId());
        assert (list.size() == 1);
        assert (list.get(0).getVideoPosition().equals("100.1"));
        assert (0 == list.get(0).getWatchEnd().compareTo(1));
    }


    /**
     * 测试课程总进度
     */

    @Test
    void test_flush_to_course_percent(){

        int max=1000,min=1;
        Integer courseId = (int) (Math.random()*(max-min)+min);

        //测试课程插入2个视频
        CourseChapterVideo video1 = new CourseChapterVideo();
        video1.setVideoName("测试视频1");
        video1.setChapterId(0);
        video1.setVideoUrl("fff");
        video1.setIsFree(0);
        video1.setCourseId(courseId);
        video1.setFreeTime(10);

        videoService.insert(video1);
        //随机数当作COURSE用


        //插入第一个进度
        UserVideoPosition userVideoPosition = new UserVideoPosition();
        userVideoPosition.setVideoId(video1.getVideoId());
        userVideoPosition.setUserId(100);
        userVideoPosition.setVideoPosition("20");
        userVideoPosition.setVideoTime("100");

        clean_redis(userVideoPosition);
        userVideoPositionService.insertPositionToRedis(userVideoPosition,courseId);



        //插入视频2
        CourseChapterVideo video2 = new CourseChapterVideo();
        video2.setVideoName("测试视频1");
        video2.setChapterId(0);
        video2.setVideoUrl("fff");
        video2.setIsFree(0);
        video2.setCourseId(courseId);
        video2.setFreeTime(10);

        videoService.insert(video2);

        //刷新到数据库课程总进度
        userVideoPositionService.flushToDb(100,video1.getVideoId(),courseId,"2020",100);

        //查询总进度
        UserCourse userCourse = userCourseService.queryById(courseId);


    }


    @Test
    void test_all_course_videos_and_progress(){
        int max=1000,min=1;
        Integer courseId = (int) (Math.random()*(max-min)+min);
        Integer userId = (int) (Math.random()*(max-min)+min);


        //测试课程插入2个视频
        CourseChapterVideo video1 = new CourseChapterVideo();
        video1.setVideoName("测试视频1");
        video1.setChapterId(0);
        video1.setVideoUrl("fff");
        video1.setIsFree(0);
        video1.setCourseId(courseId);
        video1.setFreeTime(10);

        videoService.insert(video1);
        //随机数当作COURSE用

        //插入第一个进度
        UserVideoPosition userVideoPosition = new UserVideoPosition();
        userVideoPosition.setVideoId(video1.getVideoId());
        userVideoPosition.setUserId(userId);
        userVideoPosition.setVideoPosition("20");
        userVideoPosition.setVideoTime("100");

        clean_redis(userVideoPosition);
        userVideoPositionService.insertPositionToRedis(userVideoPosition,courseId);



        //插入视频2
        CourseChapterVideo video2 = new CourseChapterVideo();
        video2.setVideoName("测试视频2");
        video2.setChapterId(0);
        video2.setVideoUrl("fff");
        video2.setIsFree(0);
        video2.setCourseId(courseId);
        video2.setFreeTime(10);

        videoService.insert(video2);
        //插入第一个进度
        userVideoPosition = new UserVideoPosition();
        userVideoPosition.setVideoId(video2.getVideoId());
        userVideoPosition.setUserId(userId);
        userVideoPosition.setVideoPosition("30");
        userVideoPosition.setVideoTime("100");

        clean_redis(userVideoPosition);
        userVideoPositionService.insertPositionToRedis(userVideoPosition,courseId);


    }


}
