/**
 * 华为云对象存储服务obs
 * @date 2022-08-09 11:55:58
 * @author 黄家维
 */

import { logger } from "mslib";
import { Readable, Stream } from "stream";
import { Singleton } from "typescript-ioc";
import { IocConfigProvider } from "./Config";
import Contants from "./Contants";
import { OssService } from "./OssService";
import { ConfigCenterConfigProvider } from './ConfigCenter';

/**
 * 华为obs客户端实例
 * 
 * @see [huawei-obs](https://support.huaweicloud.com/api-obs_nodejs_sdk_api_zh/obs_39_0101.html)
 */
export let obsClient = null;

init();

async function init() {
    let ObsClient = null;

    //检测插件
    try {
        ObsClient = require('esdk-obs-nodejs');
    } catch (error) { }

    if (!ObsClient) return;

    try {
        let config = await ConfigCenterConfigProvider.getHuaweiObsConfig();
        if (!config) return;

        obsClient = new ObsClient(config);

        logger.info(`huawei-obs客户端实例创建成功,server:${config.server}`);
    } catch (error) {
        logger.error('huawei-obs客户端实例创建失败', error);
    }
}

/**
 * 非标桶
 */
let non_standard_bucket = 'ddd-nonstandar';

/**
 * 文件根地址
 */
let accessBaseUrl = 'http://dddfile.keytop.cn';

/**
 * 华为obs响应
 */
export class HuaWeiObsResponse {
    /**
     * 判断华为接口响应是否为成功
     */
    static statusIsSuccess(status: number) {
        return status === 200;
    }

    CommonMsg: {
        Status: number,
        Code: string,
        Message: string,
        HostId: string,
        RequestId: string,
        InterfaceResult: any,
        Id2: string
    };

    InterfaceResult: {
        ContentLength: string,
        Date: string,
        Reserved: undefined,
        RequestId: string,
        Id2: string,
        ETag: string
    };
}

/**
 * 华为obs服务
 * 
 * @see {@link OssService}
 */
@Singleton
export class HuaWeiObsService implements OssService {
    /**
     * 获取对象存放根目录
     */
    getRootPath() {
        return Contants.P_ID || IocConfigProvider.getBasicConfig()?.tapdId || 'non-standard';
    }

    /**
     * 上传对象到huawei-obs
     * 
     * @returns 对象地址
     */
    put(data: string | Buffer | Stream, name: string): Promise<string> {
        return new Promise((resolve, reject) => {
            let fullname = `${this.getRootPath()}/${name}`;

            obsClient.putObject({
                Bucket: non_standard_bucket,
                Key: fullname,
                Body: Buffer.isBuffer(data) ? Readable.from(data) : data
            }, (err: any, res: HuaWeiObsResponse) => {
                if (err) reject(err);
                if (!HuaWeiObsResponse.statusIsSuccess(res?.CommonMsg.Status)) {
                    reject(res);
                }

                let url = `${accessBaseUrl}/${fullname}`;
                logger.info(`huawei-obs 上传对象成功,对象访问地址:${url}`);

                resolve(url);
            });
        })
    }
} 