package com.brframework.webapppatch.service.impl;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import com.brframework.commondb.core.AbstractEntityService;
import com.brframework.commondb.core.CommonRepository;
import com.brframework.commondistributed.annotation.DistributedLock;
import com.brframework.commonweb.exception.HandleException;
import com.brframework.webapppatch.dao.AppVersionDao;
import com.brframework.webapppatch.entity.AppVersion;
import com.brframework.webapppatch.entity.PatchBranch;
import com.brframework.webapppatch.entity.PatchVersion;
import com.brframework.webapppatch.service.AppVersionService;
import com.brframework.webapppatch.service.PatchBranchService;
import com.brframework.webapppatch.service.PatchGrayUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.LocalDateTime;

/**
 * App版本更新
 * @author xu
 * @date 2019/11/14 21:15
 */
@Service
public class AppVersionServiceImpl extends AbstractEntityService<AppVersion, Long, Object>
        implements AppVersionService {

    @Autowired
    AppVersionDao appVersionDao;
    @Autowired
    PatchGrayUserService grayUserService;

    @Override
    public CommonRepository<Long, AppVersion> getRepository() {
        return appVersionDao;
    }


    @Override
    @DistributedLock(key = "'AppVersionServiceImpl-createVersion'", waitFor = false)
    public void createVersion(String os, String version, String versionName, String versionMessage, String versionUrl, Integer updateType) {
        os = os.toUpperCase();

        //创建新版本时，当前最新的版本必须处于发布或失败的状态下
        AppVersion nowVersion = appVersionDao.findTop1ByOsOrderByCreateDateDesc(os);
        if(nowVersion != null){
            if(nowVersion.getUpdateStatus().equals(PatchVersion.UPDATE_STATUS_DEPLOY) ||
                    nowVersion.getUpdateStatus().equals(PatchVersion.UPDATE_STATUS_GRAY)){
                throw new HandleException("最新版本【" + nowVersion.getVersion()  +"】" +
                        "正处于部署或灰度状态，请在管理控制台设置发布或失败");
            }
        }

        //获取文件的大小
        HttpResponse versionResponse = HttpUtil.createRequest(Method.HEAD, versionUrl).execute();

        AppVersion newVersion = new AppVersion();
        newVersion.setCreateDate(LocalDateTime.now());
        newVersion.setVersionName(versionName);
        newVersion.setOs(os);
        newVersion.setUpdateStatus(PatchVersion.UPDATE_STATUS_DEPLOY);
        newVersion.setUpdateType(updateType);
        newVersion.setVersion(version);
        newVersion.setVersionMessage(versionMessage);
        newVersion.setVersionUrl(versionUrl);
        newVersion.setFileSize(Long.parseLong(versionResponse.header("Content-Length")));

        save(newVersion);
    }

    @Override
    public AppVersion getVersion(String os, String username) {
        os = os.toUpperCase();
        AppVersion nowVersion = appVersionDao.findTop1ByOsOrderByCreateDateDesc(os);
        if(nowVersion == null){
            nowVersion = new AppVersion();
            nowVersion.setVersion("-1");
            nowVersion.setVersionMessage("版本不存在");
            return nowVersion;
        }

        if(nowVersion.getUpdateStatus().equals(AppVersion.UPDATE_STATUS_RELEASE)){
            //最新版本处于发布状态
            return nowVersion;
        } else if(nowVersion.getUpdateStatus().equals(AppVersion.UPDATE_STATUS_GRAY)){
            //最新版本处于灰度状态
            if(StringUtils.isNotEmpty(username) && grayUserService.isGrayUser(username)){
                return nowVersion;
            }
        }

        //最后一个发布的版本
        return appVersionDao.findTop1ByOsAndUpdateStatusOrderByCreateDateDesc(os, AppVersion.UPDATE_STATUS_RELEASE);
    }

    @Override
    @DistributedLock(key = "'AppVersionServiceImpl-UpdateStatus' + #id", waitFor = false)
    public void setVersionGray(Long id) {
        AppVersion version = accessObject(id);
        if(!version.getUpdateStatus().equals(PatchVersion.UPDATE_STATUS_DEPLOY)){
            throw new HandleException("当前版本不能进入灰度发布");
        }
        version.setUpdateStatus(PatchVersion.UPDATE_STATUS_GRAY);
        save(version);
    }

    @Override
    @DistributedLock(key = "'AppVersionServiceImpl-UpdateStatus' + #id", waitFor = false)
    public void setVersionRelease(Long id) {
        AppVersion version = accessObject(id);
        if(!version.getUpdateStatus().equals(PatchVersion.UPDATE_STATUS_GRAY)){
            throw new HandleException("当前版本还不能进行发布");
        }
        version.setUpdateStatus(PatchVersion.UPDATE_STATUS_RELEASE);
        save(version);
    }

    @Override
    @DistributedLock(key = "'AppVersionServiceImpl-UpdateStatus' + #id", waitFor = false)
    public void setVersionDefeated(Long id) {
        AppVersion version = accessObject(id);
        if(version.getUpdateStatus().equals(PatchVersion.UPDATE_STATUS_RELEASE)){
            throw new HandleException("当前版本不能失败");
        }
        version.setUpdateStatus(PatchVersion.UPDATE_STATUS_DEFEATED);
        save(version);
    }
}
