import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
import { Upload } from '@aws-sdk/lib-storage'
import { PassThrough, Readable } from 'stream'
import { WritableStreamBuffer } from 'stream-buffers'
import * as path from 'path'
import { Logger } from '@nestjs/common'

export async function uploadUml(plantUml) {
    const s3 = new S3Client({
        region: process.env.ALIYUN_OSS_REGION,
        endpoint: `https://${process.env.ALIYUN_OSS_ENDPOINT}`,
        credentials: {
            accessKeyId: process.env.ALIYUN_ACCESS_KEY_ID,
            secretAccessKey: process.env.ALIYUN_ACCESS_KEY_SECRET
        }
    })
    const stream = new PassThrough()
    const key = `uml/${Date.now()}.png`

    const upload = new Upload({
        client: s3,
        params: {
            ACL: 'public-read',
            Bucket: process.env.ALIYUN_OSS_BUCKET,
            Key: key,
            Body: stream
        }
    })
    const { execa } = await (eval('import("execa")') as Promise<typeof import('execa')>)
    const puml = execa('java', [
        '-jar',
        '-Djava.awt.headless=true',
        '-DPLANTUML_LIMIT_SIZE=8192',
        `${path.join(__dirname, '../../../res/plantuml-1.2023.12.jar')}`,
        '-config',
        `${path.join(__dirname, '../../../res/plantuml.cfg')}`,
        '-tpng',
        '-pipe',
        '-fastfail',
        '-noerror'
    ])
    // convert -units PixelsPerInch - -density 300 -
    const convert = execa('convert', ['-units', 'PixelsPerInch', '-', '-density', '300', '-'])
    Readable.from(plantUml).pipe(puml.stdin)
    puml.pipeStdout(convert.stdin)
    convert.pipeStdout(stream)

    const err = new WritableStreamBuffer()
    puml.pipeStderr(err)
    try {
        await puml
    } catch (error) {
        throw new Error(err.getContents().toString())
    }
    await upload.done()
    return `https://${process.env.ALIYUN_OSS_BUCKET}.${process.env.ALIYUN_OSS_ENDPOINT}/${key}`
}

export async function uploadDoc(title, content) {
    Logger.log(`title: ${title}`, '生成docx')
    const s3 = new S3Client({
        region: process.env.ALIYUN_OSS_REGION,
        endpoint: `https://${process.env.ALIYUN_OSS_ENDPOINT}`,
        credentials: {
            accessKeyId: process.env.ALIYUN_ACCESS_KEY_ID,
            secretAccessKey: process.env.ALIYUN_ACCESS_KEY_SECRET
        }
    })
    const stream = new PassThrough()
    const key = `doc/${title}_${Date.now()}.docx`

    const upload = new Upload({
        client: s3,
        params: {
            ACL: 'public-read',
            Bucket: process.env.ALIYUN_OSS_BUCKET,
            Key: key,
            Body: stream
        }
    })

    const { execa } = await (eval('import("execa")') as Promise<typeof import('execa')>)
    const p = execa('pandoc', ['-f', 'markdown', '-t', 'docx'])
    Readable.from(content).pipe(p.stdin)
    const err = new WritableStreamBuffer()
    p.pipeStdout(stream)
    p.pipeStderr(err)
    try {
        await p
    } catch (error) {
        Logger.error(error.message, error.stack)
        Logger.error(err.getContents().toString())
        throw new Error(err.getContents().toString())
    }
    await upload.done()
    return `https://${process.env.ALIYUN_OSS_BUCKET}.${process.env.ALIYUN_OSS_ENDPOINT}/${key}`
}
