import { CloudFormationCustomResourceEvent, Context } from 'aws-lambda';
import { request } from 'https';
import { URL } from 'url';

export enum CustomResourceResponseStatus {
    success = 'SUCCESS',
    failed = 'FAILED'
}

type CustomResourceResponseProps = {
    status: CustomResourceResponseStatus
    reason?: string;

    event: CloudFormationCustomResourceEvent,
    context: Context,
    physicalResourceId: string,

    data?: { [key: string]: any },
};

export const send = async (props: CustomResourceResponseProps) => new Promise<void>(async (resolve, reject) => {
    const url = new URL(props.event.ResponseURL);

    const responseBody = JSON.stringify({
        Status: props.status,
        Reason: props.reason || `More information can be found by accessing the following CloudWatch Log Stream: ${props.context.logStreamName}`,

        PhysicalResourceId: props.physicalResourceId || props.context.logStreamName,
        StackId: props.event.StackId,
        RequestId: props.event.RequestId,
        LogicalResourceId: props.event.LogicalResourceId,

        Data: props.data
    });

    const httpsRequest = request(url, {
        method: 'PUT',
        port: 443,
        headers: {
            "content-type": "application/json",
            "content-length": responseBody.length
        }
    }, (response) => {
        console.log(`[cfn-response] Status code: ${response.statusCode}`);
        console.log(`[cfn-response] Status message: ${response.statusMessage}`);

        if (response.statusCode !== 200) {
            console.error(`[cfn-response] Invalid response status code ${response.statusCode}`);
            return resolve();
        }

        response.on('end', () => {
            return resolve();
        });

        response.on('error', (err) => {
            console.error(`[cfn-response] Response error`);
            console.error(err);
            return resolve();
        });
    });

    httpsRequest.on('error', (err) => {
        console.error(`[cfn-response] Request failed`);
        console.error(err);
        return resolve();
    });

    httpsRequest.write(responseBody);
    httpsRequest.end();
});