/**
 * Project Name:tuia-youtui-web<br>
 * File Name:ConsumerBOImpl.java<br>
 * Package Name:com.duiba.tuia.youtui.web.bo.impl<br>
 * Date:2017年1月22日上午9:56:09<br>
 * Copyright (c) 2017, duiba.com.cn All Rights Reserved.<br>
 */

package com.duiba.tuia.youtui.web.service.impl;


import cn.com.duiba.tuia.ssp.center.api.dto.MediaAppDataDto;
import cn.com.duiba.tuia.ssp.center.api.dto.MediaAppDto;
import cn.com.duiba.tuia.ssp.center.api.remote.RemoteMediaAppService;
import cn.com.duiba.tuia.ssp.center.api.remote.RemoteMediaService;
import cn.com.duiba.wolf.dubbo.DubboResult;
import com.duiba.tuia.youtui.web.constant.ErrorCode;
import com.duiba.tuia.youtui.web.exception.ActivityException;
import com.duiba.tuia.youtui.web.service.AppService;
import com.duiba.tuia.youtui.web.service.BaseService;
import com.duiba.tuia.youtui.web.tool.RequestLocal;
import com.duiba.tuia.youtui.web.tool.RequestTool;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * ClassName: ConsumerBOImpl <br/>
 * Function: 用户. <br/>
 * date: 2017年1月22日 上午9:56:09 <br/>
 *
 * @author leiliang update chengdeman 2017-07-14  去除依赖 developer-center 使用ssp－center的接口
 * @since JDK 1.6
 */
@Service
public class AppServiceImpl extends BaseService implements AppService, InitializingBean {


    @Autowired
    private RemoteMediaService remoteMediaService;

    @Autowired
    protected RemoteMediaAppService remoteMediaAppService;

    private LoadingCache<String, MediaAppDataDto> appLoader;

    private LoadingCache<Long, Optional<MediaAppDto>> appDataLoader;

    @Override
    public MediaAppDataDto findAppByAppKey(String appKey) throws ExecutionException {
        return appLoader.get(appKey);
    }

    @Override
    public Optional<MediaAppDto> getMediaApp(Long appId) {
        try {
            return appDataLoader.get(appId);
        } catch (Exception e) {
            logger.warn("app缓存不存在，appId=[{}]，IP=[{}]", appId, RequestTool.getIpAddr(RequestLocal.get().getRequest()), e);
            return Optional.empty();
        }
    }

    /**
     * 刷新缓存的方法
     *
     * @param appId  媒体id
     * @param appKey 媒体key
     */
    @Override
    public void refreshCache(Long appId, String appKey) {
        appLoader.refresh(appKey);
        appDataLoader.refresh(appId);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        appLoader = CacheBuilder.newBuilder()
                .maximumSize(2000)
                .expireAfterWrite(20, TimeUnit.MINUTES)//每20min刷新缓存
                .build(new CacheLoader<String, MediaAppDataDto>() {

                    @Override
                    public MediaAppDataDto load(String appKey) throws Exception {
                        DubboResult<MediaAppDataDto> appResult = remoteMediaService.getMediaAppByKey(appKey);
                        if (!appResult.isSuccess()) {
                            logger.warn("remoteMediaService.getMediaAppByKey happen error, the appKey=[{}], and because of=[{}]", appKey, appResult.getMsg());
                            throw new ActivityException(ErrorCode.E0300001);
                        }

                        if (appResult.getResult() == null) {
                            throw new ActivityException(ErrorCode.E0300002);
                        }
                        return appResult.getResult();
                    }
                });

        appDataLoader = CacheBuilder.newBuilder().maximumSize(2000)
                .expireAfterWrite(20, TimeUnit.MINUTES)//每20min刷新缓存
                .build(new CacheLoader<Long, Optional<MediaAppDto>>() {

                    @Override
                    public Optional<MediaAppDto> load(Long appId) throws Exception {
                        DubboResult<MediaAppDto> appResult = remoteMediaAppService.getMediaApp(appId);
                        if (!appResult.isSuccess()) {
                            logger.warn("remoteMediaAppService.getMediaApp happen error, the appId=[{}], and because of=[{}]", appId, appResult.getMsg());
                            return Optional.empty();
                        }

                        return Optional.of(appResult.getResult());
                    }
                });
    }
}
