#!/usr/bin/perl

# (C) Nginx, Inc.

# Promise tests for http njs module.

###############################################################################

use warnings;
use strict;

use Test::More;

BEGIN { use FindBin; chdir($FindBin::Bin); }

use lib 'lib';
use Test::Nginx;

###############################################################################

select STDERR; $| = 1;
select STDOUT; $| = 1;

my $t = Test::Nginx->new()->has(qw/http/)
	->write_file_expand('nginx.conf', <<'EOF');

%%TEST_GLOBALS%%

daemon off;

events {
}

http {
    %%TEST_GLOBALS_HTTP%%

    js_include test.js;

    server {
        listen       127.0.0.1:8080;
        server_name  localhost;

        location /njs {
            js_content test_njs;
        }

        location /promise {
            js_content promise;
        }

        location /promise_throw {
            js_content promise_throw;
        }

        location /promise_pure {
            js_content promise_pure;
        }

        location /timeout {
            js_content timeout;
        }

        location /sub_token {
            js_content sub_token;
        }
    }
}

EOF

$t->write_file('test.js', <<EOF);
    var global_token = '';

    function test_njs(r) {
        r.return(200, njs.version);
    }

    function promise(r) {
        promisified_subrequest(r, '/sub_token', 'code=200&token=a')
        .then(reply => {
            var data = JSON.parse(reply.responseBody);

            if (data['token'] !== "a") {
                throw new Error('token is not "a"');
            }

            return data['token'];
        })
        .then(token => {
            promisified_subrequest(r, '/sub_token', 'code=200&token=b')
            .then(reply => {
                var data = JSON.parse(reply.responseBody);

                r.return(200, '{"token": "' + data['token'] + '"}');
            })
            .catch(() => {
                throw new Error("failed promise() test");
            });
        })
        .catch(() => {
            r.return(500);
        });
    }

    function promise_throw(r) {
        promisified_subrequest(r, '/sub_token', 'code=200&token=x')
        .then(reply => {
            var data = JSON.parse(reply.responseBody);

            if (data['token'] !== "a") {
                throw data['token'];
            }

            return data['token'];
        })
        .then(() => {
            r.return(500);
        })
        .catch(token => {
            r.return(200, '{"token": "' + token + '"}');
        });
    }

    function promise_pure(r) {
        var count = 0;

        Promise.resolve(true)
        .then(() => count++)
        .then(() => not_exist_ref)
        .finally(() => count++)
        .catch(() => {
            r.return((count != 2) ? 500 : 200);
        });
    }

    function timeout(r) {
        promisified_subrequest(r, '/sub_token', 'code=200&token=R')
        .then(reply => JSON.parse(reply.responseBody))
        .then(data => {
            setTimeout(timeout_cb, 50, r, '/sub_token', 'code=200&token=T');
            return data;
        })
        .then(data => {
            setTimeout(timeout_cb, 1, r, '/sub_token', 'code=200&token='
                                                        + data['token']);
        })
        .catch(() => {
            r.return(500);
        });
    }

    function timeout_cb(r, url, args) {
        promisified_subrequest(r, url, args)
        .then(reply => {
            if (global_token == '') {
                var data = JSON.parse(reply.responseBody);

                global_token = data['token'];

                r.return(200, '{"token": "' + data['token'] + '"}');
            }
        })
        .catch(() => {
            r.return(500);
        });
    }

    function promisified_subrequest(r, uri, args) {
        return new Promise((resolve, reject) => {
            r.subrequest(uri, args, (reply) => {
                if (reply.status < 400) {
                    resolve(reply);
                } else {
                    reject(reply);
                }
            });
        })
    }

    function sub_token(r) {
        var code = r.variables.arg_code;
        var token = r.variables.arg_token;

        r.return(parseInt(code), '{"token": "'+ token +'"}');
    }

EOF

$t->try_run('no njs available')->plan(4);

###############################################################################

like(http_get('/promise'), qr/{"token": "b"}/, "Promise");
like(http_get('/promise_throw'), qr/{"token": "x"}/, "Promise throw and catch");
like(http_get('/timeout'), qr/{"token": "R"}/, "Promise with timeout");

TODO: {
local $TODO = 'not yet'
	unless http_get('/njs') =~ /^([.0-9]+)$/m && $1 ge '0.5.0';

like(http_get('/promise_pure'), qr/200 OK/, "events handling");
}

$t->todo_alerts() unless http_get('/njs') =~ /^([.0-9]+)$/m && $1 ge '0.5.0';

###############################################################################
