import http, { request as httpRequest } from 'http'
import https, { request as httpsRequest } from 'https'

export interface GetResult<T> {
    data?: T
    error?: Error
    options?: http.RequestOptions
}

export function get<T = any>(
    options: http.RequestOptions,
    useHttp?: boolean
): Promise<GetResult<T>> {
    const provider = useHttp ? http : https

    return new Promise((resolve) => {
        const req = provider.get(options, function (res) {
            const bodyChunks: Uint8Array[] = []
            res.on('data', (chunk) => {
                bodyChunks.push(chunk)
            }).on('end', () => {
                const body = Buffer.concat(bodyChunks).toString()
                try {
                    resolve({ data: JSON.parse(body) })
                } catch (e) {
                    console.log(body)
                    resolve({ error: e, options: options })
                }
            })
        })
        req.on('error', function (e) {
            resolve({ error: e, options: options })
        })
    })
}

export interface PostResult<T> {
    data?: T
    error?: Error
    cookies?: string[]
}

interface PostParams {
    hostname: string
    path: string
    port: number
    bodyObject: any
    http?: boolean
}

// https://nodejs.org/api/http.html#httprequesturl-options-callback
export function post<T = any>({
    hostname,
    path,
    port,
    bodyObject,
    http,
}: PostParams): Promise<PostResult<T>> {
    const provider = http ? httpRequest : httpsRequest
    const body = JSON.stringify(bodyObject)

    return new Promise((resolve) => {
        const req = provider(
            {
                hostname: hostname,
                port: port,
                path: path,
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Content-Length': Buffer.byteLength(body),
                },
            },
            (res) => {
                const bodyChunks: string[] = []
                res.setEncoding('utf8')
                res.on('data', (chunk) => {
                    bodyChunks.push(chunk)
                })
                res.on('end', () => {
                    const body = bodyChunks.join()
                    try {
                        resolve({
                            data: JSON.parse(body),
                            cookies: res.headers['set-cookie'],
                        })
                    } catch (e) {
                        console.log(body)
                        resolve({ error: e })
                    }
                })
            }
        )

        req.on('error', (e) => {
            resolve({ error: e })
        })

        req.write(body)
        req.end()
    })
}
