'use strict';

const path = require('path');
const util = require('util');
const CodeBuilder = require(path.dirname(require.resolve('httpsnippet')) + '/helpers/code-builder');

module.exports = (endpoint, options) => {

    let source = require('./base-snippet')(endpoint, Object.assign({har: true}, options), 'php', 'curl');

    let opts = util._extend({
        closingTag: false,
        indent: '  ',
        maxRedirects: 10,
        namedErrors: false,
        noTags: false,
        shortTags: false,
        timeout: 30

    }, {
        maxRedirects: 3,
        timeout: 60,
        namedErrors: true,
    });

    let code = new CodeBuilder(opts.indent);

    if(!opts.noTags) {
        code.push(opts.shortTags ? '<?' : '<?php')
            .blank()
    }

    code.push('$curl = curl_init();')
        .blank();

    let queryStr = false;

    if(source.queryString.length > 0) {
        queryStr = true;

        code.push('$queryStr = array(')
            .push(1, source.queryString.map(query => {
                    if(query.comment) {
                        return util.format('"%s" => %s, // %s', query.name, JSON.stringify(query.value), query.comment.substring(0, 60))
                    }

                    return util.format('"%s" => %s,', query.name, JSON.stringify(query.value))
                })
                .join('\n' + opts.indent)
            )
            .push(');')
            .blank();
    }

    let curlOptions = [{
        escape: true,
        name: 'CURLOPT_PORT',
        value: parseInt(source.uriObj.port)
    }, {
        escape: false,
        name: 'CURLOPT_URL',
        value: JSON.stringify(source.url) + (queryStr ? ' . "?" . http_build_query($queryStr)' : ''),
    }, {
        escape: false,
        name: 'CURLOPT_RETURNTRANSFER',
        value: 'true'
    }, {
        escape: true,
        name: 'CURLOPT_ENCODING',
        value: ''
    }, {
        escape: false,
        name: 'CURLOPT_MAXREDIRS',
        value: opts.maxRedirects
    }, {
        escape: false,
        name: 'CURLOPT_TIMEOUT',
        value: opts.timeout
    }, {
        escape: false,
        name: 'CURLOPT_HTTP_VERSION',
        value: source.httpVersion === 'HTTP/1.0' ? 'CURL_HTTP_VERSION_1_0' : 'CURL_HTTP_VERSION_1_1'
    }, {
        escape: true,
        name: 'CURLOPT_CUSTOMREQUEST',
        value: source.method
    }, {
        escape: true,
        name: 'CURLOPT_POSTFIELDS',
        value: source.postData ? source.postData.text : undefined
    }];

    code.push('curl_setopt_array($curl, array(');

    let curlopts = new CodeBuilder(opts.indent, '\n' + opts.indent)

    curlOptions.forEach(function(option) {
        if(!~[null, undefined].indexOf(option.value)) {
            curlopts.push(util.format('%s => %s,', option.name, option.escape ? JSON.stringify(option.value) : option.value))
        }
    });

    // construct cookies
    let cookies = source.cookies.map(function(cookie) {
        return encodeURIComponent(cookie.name) + '=' + encodeURIComponent(cookie.value)
    });

    if(cookies.length) {
        curlopts.push(util.format('CURLOPT_COOKIE => "%s",', cookies.join('; ')))
    }

    // construct cookies
    let headers = [];

    source.headers.forEach(header => {
        let headerStr = '';

        if(header.comment) {
            headerStr = util.format('"%s: %s", // %s', header.name, header.value, header.comment);

        } else {
            headerStr = util.format('"%s: %s",', header.name, header.value);
        }

        headers.push(headerStr);
    });

    // let headers = Object.keys(source.headersObj).sort().map(function(key) {
    //     return util.format('"%s: %s"', key, source.headersObj[key])
    // });

    if(headers.length) {
        curlopts.push('CURLOPT_HTTPHEADER => array(')
            .push(1, headers.join('\n' + opts.indent + opts.indent))
            .push('),')
    }

    code.push(1, curlopts.join())
        .push('));')
        .blank()
        .push('$response = curl_exec($curl);')
        .push('$err = curl_error($curl);')
        .blank()
        .push('curl_close($curl);')
        .blank()
        .push('if ($err) {');

    if(opts.namedErrors) {
        code.push(1, 'echo array_flip(get_defined_constants(true)["curl"])[$err];')
    } else {
        code.push(1, 'echo "cURL Error #:" . $err;')
    }

    code.push('} else {')
        .push(1, 'echo $response;')
        .push('}');

    if(!opts.noTags && opts.closingTag) {
        code.blank()
            .push('?>');
    }

    return code.join();
};