/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "uv.h"
#include "task.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int connect_cb_called;
static int write_cb_called;
static int close_cb_called;


static void close_cb(uv_handle_t* handle) {
  close_cb_called++;
}


static void connect_cb(uv_connect_t* req, int status) {
  ASSERT(status == -1);
  connect_cb_called++;
  uv_close((uv_handle_t*)req->handle, close_cb);
}


static void write_cb(uv_write_t* req, int status) {
  ASSERT(status == -1);
  write_cb_called++;
}


/*
 * Try to connect to an address on which nothing listens, get ECONNREFUSED
 * (uv errno 12) and get connect_cb() called once with status != 0.
 * Related issue: https://github.com/joyent/libuv/issues/443
 */
TEST_IMPL(tcp_connect_error_after_write) {
  uv_connect_t connect_req;
  struct sockaddr_in addr;
  uv_write_t write_req;
  uv_tcp_t conn;
  uv_buf_t buf;
  int r;

#ifdef _WIN32
  fprintf(stderr, "This test is disabled on Windows for now.\n");
  fprintf(stderr, "See https://github.com/joyent/libuv/issues/444\n");
  return 0; /* windows slackers... */
#endif

  addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
  buf = uv_buf_init("TEST", 4);

  r = uv_tcp_init(uv_default_loop(), &conn);
  ASSERT(r == 0);

  r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb);
  ASSERT(r == -1);
  ASSERT(uv_last_error(uv_default_loop()).code == UV_EBADF);

  r = uv_tcp_connect(&connect_req, &conn, addr, connect_cb);
  ASSERT(r == 0);

  r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb);
  ASSERT(r == 0);

  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
  ASSERT(r == 0);

  ASSERT(connect_cb_called == 1);
  ASSERT(write_cb_called == 1);
  ASSERT(close_cb_called == 1);

  MAKE_VALGRIND_HAPPY();
  return 0;
}
