/*
  PIM for Quagga
  Copyright (C) 2008  Everton da Silva Marques

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this program; see the file COPYING; if not, write to the
  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  MA 02110-1301 USA
  
  $QuaggaId: $Format:%an, %ai, %h$ $
*/

#include <zebra.h>
#include "zebra/rib.h"

#include "log.h"
#include "prefix.h"
#include "zclient.h"
#include "stream.h"
#include "network.h"
#include "thread.h"

#include "pimd.h"
#include "pim_pim.h"
#include "pim_str.h"
#include "pim_zlookup.h"

extern int zclient_debug;

static void zclient_lookup_sched(struct zclient *zlookup, int delay);

/* Connect to zebra for nexthop lookup. */
static int zclient_lookup_connect(struct thread *t)
{
  struct zclient *zlookup;

  zlookup = THREAD_ARG(t);
  zlookup->t_connect = NULL;

  if (zlookup->sock >= 0) {
    return 0;
  }

#ifdef PIM_ZCLIENT_DEBUG

#ifdef HAVE_TCP_ZEBRA
  zlog_debug("%s: FIXME blocking connect: zclient_socket()",
	     __PRETTY_FUNCTION__);
  zlookup->sock = zclient_socket();
  if (zlookup->sock < 0) {
    zlog_warn("%s: failure connecting TCP socket %s,%d",
	      __PRETTY_FUNCTION__, "127.0.0.1", ZEBRA_PORT);
  }
  else if (zclient_debug) {
    zlog_notice("%s: connected TCP socket %s,%d",
		__PRETTY_FUNCTION__, "127.0.0.1", ZEBRA_PORT);
  }
#else
  zlog_debug("%s: FIXME blocking connect: zclient_socket_un()",
	     __PRETTY_FUNCTION__);
  zlookup->sock = zclient_socket_un(ZEBRA_SERV_PATH);
  if (zlookup->sock < 0) {
    zlog_warn("%s: failure connecting UNIX socket %s",
	      __PRETTY_FUNCTION__, ZEBRA_SERV_PATH);
  }
  else if (zclient_debug) { 
    zlog_notice("%s: connected UNIX socket %s",
		__PRETTY_FUNCTION__, ZEBRA_SERV_PATH);
  }
#endif /* HAVE_TCP_ZEBRA */

#else

  zlog_debug("%s: FIXME blocking connect: zclient_socket_connect()",
	     __PRETTY_FUNCTION__);
  if (zclient_socket_connect(zlookup) < 0) {
    zlog_warn("%s: failure connecting zclient socket",
	      __PRETTY_FUNCTION__);
  }

#endif /* PIM_ZCLIENT_DEBUG */

  zassert(!zlookup->t_connect);
  if (zlookup->sock < 0) {
    /* Since last connect failed, retry within 10 secs */
    zclient_lookup_sched(zlookup, 10);
    return -1;
  }

  return 0;
}

/* Schedule connection with delay. */
static void zclient_lookup_sched(struct zclient *zlookup, int delay)
{
  zassert(!zlookup->t_connect);

  THREAD_TIMER_ON(master, zlookup->t_connect,
		  zclient_lookup_connect,
		  zlookup, delay);

  zlog_notice("%s: zclient lookup connection scheduled for %d seconds",
	      __PRETTY_FUNCTION__, delay);
}

/* Schedule connection for now. */
static void zclient_lookup_sched_now(struct zclient *zlookup)
{
  zassert(!zlookup->t_connect);

  zlookup->t_connect = thread_add_event(master, zclient_lookup_connect,
					zlookup, 0);

  zlog_notice("%s: zclient lookup immediate connection scheduled",
	      __PRETTY_FUNCTION__);
}

/* Schedule reconnection, if needed. */
static void zclient_lookup_reconnect(struct zclient *zlookup)
{
  if (zlookup->t_connect) {
    return;
  }

  zclient_lookup_sched_now(zlookup);
}

struct zclient *zclient_lookup_new()
{
  struct zclient *zlookup;

  zlookup = zclient_new();
  if (!zlookup) {
    zlog_err("%s: zclient_new() failure",
	     __PRETTY_FUNCTION__);
    return 0;
  }

  zlookup->sock = -1;
  zlookup->ibuf = stream_new(ZEBRA_MAX_PACKET_SIZ);
  zlookup->obuf = stream_new(ZEBRA_MAX_PACKET_SIZ);
  zlookup->t_connect = 0;

  zclient_lookup_sched_now(zlookup);

  zlog_notice("%s: zclient lookup socket initialized",
	      __PRETTY_FUNCTION__);

  return zlookup;
}

static int zclient_read_nexthop(struct zclient *zlookup,
				struct pim_zlookup_nexthop nexthop_tab[],
				const int tab_size,
				struct in_addr addr)
{
  int num_ifindex = 0;
  struct stream *s;
  const uint16_t MIN_LEN = 14; /* getc=1 getc=1 getw=2 getipv4=4 getc=1 getl=4 getc=1 */
  uint16_t length, len;
  u_char marker;
  u_char version;
  uint16_t command;
  int nbytes;
  struct in_addr raddr;
  uint8_t distance;
  uint32_t metric;
  int nexthop_num;
  int i;

  if (PIM_DEBUG_ZEBRA) {
    char addr_str[100];
    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
    zlog_debug("%s: addr=%s", 
	       __PRETTY_FUNCTION__,
	       addr_str);
  }

  s = zlookup->ibuf;
  stream_reset(s);

  nbytes = stream_read(s, zlookup->sock, 2);
  if (nbytes < 2) {
    zlog_err("%s %s: failure reading zclient lookup socket: nbytes=%d",
	     __FILE__, __PRETTY_FUNCTION__, nbytes);
    close(zlookup->sock);
    zlookup->sock = -1;
    zclient_lookup_reconnect(zlookup);
    return -1;
  }
  length = stream_getw(s);

  len = length - 2;

  if (len < MIN_LEN) {
    zlog_err("%s %s: failure reading zclient lookup socket: len=%d < MIN_LEN=%d",
	     __FILE__, __PRETTY_FUNCTION__, len, MIN_LEN);
    close(zlookup->sock);
    zlookup->sock = -1;
    zclient_lookup_reconnect(zlookup);
    return -2;
  }

  nbytes = stream_read(s, zlookup->sock, len);
  if (nbytes < (length - 2)) {
    zlog_err("%s %s: failure reading zclient lookup socket: nbytes=%d < len=%d",
	     __FILE__, __PRETTY_FUNCTION__, nbytes, len);
    close(zlookup->sock);
    zlookup->sock = -1;
    zclient_lookup_reconnect(zlookup);
    return -3;
  }
  marker = stream_getc(s);
  version = stream_getc(s);
  
  if (version != ZSERV_VERSION || marker != ZEBRA_HEADER_MARKER) {
    zlog_err("%s: socket %d version mismatch, marker %d, version %d",
	     __func__, zlookup->sock, marker, version);
    return -4;
  }
    
  command = stream_getw(s);
  if (command != ZEBRA_IPV4_NEXTHOP_LOOKUP_V2) {
    zlog_err("%s: socket %d command mismatch: %d",
            __func__, zlookup->sock, command);
    return -5;
  }

  raddr.s_addr = stream_get_ipv4(s);

  if (raddr.s_addr != addr.s_addr) {
    char addr_str[100];
    char raddr_str[100];
    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
    pim_inet4_dump("<raddr?>", raddr, raddr_str, sizeof(raddr_str));
    zlog_warn("%s: address mismatch: addr=%s raddr=%s", 
	       __PRETTY_FUNCTION__,
	       addr_str, raddr_str);
    /* warning only */
  }

  distance = stream_getc(s);
  metric = stream_getl(s);
  nexthop_num = stream_getc(s);

  if (nexthop_num < 1) {
    zlog_err("%s: socket %d bad nexthop_num=%d",
            __func__, zlookup->sock, nexthop_num);
    return -6;
  }

  len -= MIN_LEN;

  for (i = 0; i < nexthop_num; ++i) {
    enum nexthop_types_t nexthop_type;

    if (len < 1) {
      zlog_err("%s: socket %d empty input expecting nexthop_type: len=%d",
	       __func__, zlookup->sock, len);
      return -7;
    }
    
    nexthop_type = stream_getc(s);
    --len;

    switch (nexthop_type) {
    case ZEBRA_NEXTHOP_IFINDEX:
    case ZEBRA_NEXTHOP_IFNAME:
    case ZEBRA_NEXTHOP_IPV4_IFINDEX:
      if (num_ifindex >= tab_size) {
	char addr_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	zlog_warn("%s %s: found too many nexthop ifindexes (%d > %d) for address %s",
		 __FILE__, __PRETTY_FUNCTION__,
		 (num_ifindex + 1), tab_size, addr_str);
	return num_ifindex;
      }
      if (nexthop_type == ZEBRA_NEXTHOP_IPV4_IFINDEX) {
	if (len < 4) {
	  zlog_err("%s: socket %d short input expecting nexthop IPv4-addr: len=%d",
		   __func__, zlookup->sock, len);
	  return -8;
	}
	nexthop_tab[num_ifindex].nexthop_addr.s_addr = stream_get_ipv4(s);
	len -= 4;
      }
      else {
	nexthop_tab[num_ifindex].nexthop_addr.s_addr = PIM_NET_INADDR_ANY;
      }
      nexthop_tab[num_ifindex].ifindex           = stream_getl(s);
      nexthop_tab[num_ifindex].protocol_distance = distance;
      nexthop_tab[num_ifindex].route_metric      = metric;
      ++num_ifindex;
      break;
    case ZEBRA_NEXTHOP_IPV4:
      if (num_ifindex >= tab_size) {
	char addr_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	zlog_warn("%s %s: found too many nexthop ifindexes (%d > %d) for address %s",
		 __FILE__, __PRETTY_FUNCTION__,
		 (num_ifindex + 1), tab_size, addr_str);
	return num_ifindex;
      }
      nexthop_tab[num_ifindex].nexthop_addr.s_addr = stream_get_ipv4(s);
      len -= 4;
      nexthop_tab[num_ifindex].ifindex             = 0;
      nexthop_tab[num_ifindex].protocol_distance   = distance;
      nexthop_tab[num_ifindex].route_metric        = metric;
      {
	char addr_str[100];
	char nexthop_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	pim_inet4_dump("<nexthop?>", nexthop_tab[num_ifindex].nexthop_addr, nexthop_str, sizeof(nexthop_str));
	zlog_warn("%s %s: zebra returned recursive nexthop %s for address %s",
		  __FILE__, __PRETTY_FUNCTION__,
		  nexthop_str, addr_str);
      }
      ++num_ifindex;
      break;
    default:
      /* do nothing */
      {
	char addr_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	zlog_warn("%s %s: found non-ifindex nexthop type=%d for address %s",
		 __FILE__, __PRETTY_FUNCTION__,
		  nexthop_type, addr_str);
      }
      break;
    }
  }

  return num_ifindex;
}

static int zclient_lookup_nexthop_once(struct zclient *zlookup,
				       struct pim_zlookup_nexthop nexthop_tab[],
				       const int tab_size,
				       struct in_addr addr)
{
  struct stream *s;
  int ret;

  if (PIM_DEBUG_ZEBRA) {
    char addr_str[100];
    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
    zlog_debug("%s: addr=%s", 
	       __PRETTY_FUNCTION__,
	       addr_str);
  }

  /* Check socket. */
  if (zlookup->sock < 0) {
    zlog_err("%s %s: zclient lookup socket is not connected",
	     __FILE__, __PRETTY_FUNCTION__);
    zclient_lookup_reconnect(zlookup);
    return -1;
  }
  
  s = zlookup->obuf;
  stream_reset(s);
  zclient_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_V2);
  stream_put_in_addr(s, &addr);
  stream_putw_at(s, 0, stream_get_endp(s));
  
  ret = writen(zlookup->sock, s->data, stream_get_endp(s));
  if (ret < 0) {
    zlog_err("%s %s: writen() failure writing to zclient lookup socket",
	     __FILE__, __PRETTY_FUNCTION__);
    close(zlookup->sock);
    zlookup->sock = -1;
    zclient_lookup_reconnect(zlookup);
    return -2;
  }
  if (ret == 0) {
    zlog_err("%s %s: connection closed on zclient lookup socket",
	     __FILE__, __PRETTY_FUNCTION__);
    close(zlookup->sock);
    zlookup->sock = -1;
    zclient_lookup_reconnect(zlookup);
    return -3;
  }
  
  return zclient_read_nexthop(zlookup, nexthop_tab,
			      tab_size, addr);
}

int zclient_lookup_nexthop(struct zclient *zlookup,
			   struct pim_zlookup_nexthop nexthop_tab[],
			   const int tab_size,
			   struct in_addr addr,
			   int max_lookup)
{
  int lookup;

  for (lookup = 0; lookup < max_lookup; ++lookup) {
    int num_ifindex;
    int first_ifindex;
    struct in_addr nexthop_addr;

    num_ifindex = zclient_lookup_nexthop_once(qpim_zclient_lookup, nexthop_tab,
					      PIM_NEXTHOP_IFINDEX_TAB_SIZE, addr);
    if (num_ifindex < 1) {
      char addr_str[100];
      pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
      zlog_warn("%s %s: lookup=%d/%d: could not find nexthop ifindex for address %s",
		__FILE__, __PRETTY_FUNCTION__,
		lookup, max_lookup, addr_str);
      return -1;
    }
    
    /*
      FIXME: Non-recursive nexthop ensured only for first ifindex.
      However, recursive route lookup should really be fixed in zebra daemon.
      See also TODO T24.
     */
    first_ifindex = nexthop_tab[0].ifindex;
    nexthop_addr = nexthop_tab[0].nexthop_addr;
    if (first_ifindex > 0) {
      /* found: first ifindex is non-recursive nexthop */

      if (lookup > 0) {
	/* Report non-recursive success after first lookup */
	char addr_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	zlog_info("%s %s: lookup=%d/%d: found non-recursive ifindex=%d for address %s",
		  __FILE__, __PRETTY_FUNCTION__,
		  lookup, max_lookup, first_ifindex, addr_str);

	/* use last address as nexthop address */
	nexthop_tab[0].nexthop_addr = addr;
      }

      return num_ifindex;
    }

    {
      char addr_str[100];
      char nexthop_str[100];
      pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
      pim_inet4_dump("<nexthop?>", nexthop_addr, nexthop_str, sizeof(nexthop_str));
      zlog_warn("%s %s: lookup=%d/%d: zebra returned recursive nexthop %s for address %s",
		__FILE__, __PRETTY_FUNCTION__,
		lookup, max_lookup, nexthop_str, addr_str);
    }

    addr = nexthop_addr; /* use nexthop addr for recursive lookup */

  } /* for (max_lookup) */

  char addr_str[100];
  pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
  zlog_warn("%s %s: lookup=%d/%d: failure searching recursive nexthop ifindex for address %s",
	    __FILE__, __PRETTY_FUNCTION__,
	    lookup, max_lookup, addr_str);

  return -2;
}
