package com.sonic.common.client;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.sonic.common.AppRuntime;
import com.sonic.common.enums.AppEnv;
import com.sonic.common.rpc.RpcClient;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

/**
 * @author chenjun
 */
public abstract class AbstractBsClient {

    @Setter
    protected AppCenterClient appCenterClient;
    @Setter
    protected String appId;
    @Setter
    protected AppEnv appEnv;
    @Setter
    protected RpcClient rpcClient;
    /**
     * 目前host是直接指定的网关的host。请求通过网关转发
     */
    @Setter
    protected String host;

    @Data
    public abstract static class Builder {
        protected AppRuntime appRuntime;
        protected RpcClient rpcClient;
        protected boolean isDummy;
        protected AppCenterClient appCenterClient;
        protected String host = "";

        protected abstract AbstractBsClient createService();

        protected AbstractBsClient buildService() {
            if (!isDummy) {
                Preconditions.checkArgument(!Strings.isNullOrEmpty(appRuntime.getAppId()), "缺少appId");
                Preconditions.checkArgument(appRuntime.getEnv() != null, "缺少appEnv");
                Preconditions.checkArgument(rpcClient != null, "缺少 rpcClient");
                Preconditions.checkArgument(appCenterClient != null, "缺少appCenterClient");
            }

            AbstractBsClient service = createService();
            service.setAppId(appRuntime.getAppId());
            service.setAppEnv(appRuntime.getEnv());
            service.setRpcClient(rpcClient);
            service.setAppCenterClient(appCenterClient);
            service.setHost(host);
            return service;
        }
    }

    /**
     * 获取服务地址前缀（通过网关访问后端服务）<br>
     * ${gatewayHost+serviceName} <br>
     * sample: http://bs-gateway.gamers.gg/bs-app-center <br>
     *
     * @return
     */
    protected String getPathPrefix() {
        return (host.endsWith("/") ? host : host + "/") + appCenterClient.getNameByAppId(serviceAppId());
    }

    /**
     * app-center维护的服务的app.id
     *
     * @return
     */
    protected abstract String serviceAppId();

    /**
     * 定义一个预置服务的枚举，方便客户端内部使用<br>
     * 该枚举仅用于提供内置服务的appId，方便阅读。
     */
    @Getter
    protected enum BuildInServiceEnum {
        APP_CENTER("0001"),
        ;

        BuildInServiceEnum(String appId) {
            this.appId = appId;
        }

        private String appId;
    }
}
