/*
 * RIPng debug output routines
 * Copyright (C) 1998 Kunihiro Ishiguro
 *
 * This file is part of GNU Zebra.
 *
 * GNU Zebra 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, or (at your option) any
 * later version.
 *
 * GNU Zebra 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 GNU Zebra; see the file COPYING.  If not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.  
 */

#include <zebra.h>
#include "command.h"
#include "ripngd/ripng_debug.h"

/* For debug statement. */
unsigned long ripng_debug_event = 0;
unsigned long ripng_debug_packet = 0;
unsigned long ripng_debug_zebra = 0;

DEFUN (show_debugging_ripng,
       show_debugging_ripng_cmd,
       "show debugging ripng",
       SHOW_STR
       DEBUG_STR
       "RIPng configuration\n")
{
  vty_out (vty, "RIPng debugging status:%s", VTY_NEWLINE);

  if (IS_RIPNG_DEBUG_EVENT)
    vty_out (vty, "  RIPng event debugging is on%s", VTY_NEWLINE);

  if (IS_RIPNG_DEBUG_PACKET)
    {
      if (IS_RIPNG_DEBUG_SEND && IS_RIPNG_DEBUG_RECV)
	{
	  vty_out (vty, "  RIPng packet debugging is on%s",
		   VTY_NEWLINE);
	}
      else
	{
	  if (IS_RIPNG_DEBUG_SEND)
	    vty_out (vty, "  RIPng packet send debugging is on%s",
		     VTY_NEWLINE);
	  else
	    vty_out (vty, "  RIPng packet receive debugging is on%s",
		     VTY_NEWLINE);
	}
    }

  if (IS_RIPNG_DEBUG_ZEBRA)
    vty_out (vty, "  RIPng zebra debugging is on%s", VTY_NEWLINE);

  return CMD_SUCCESS;
}

DEFUN (debug_ripng_events,
       debug_ripng_events_cmd,
       "debug ripng events",
       DEBUG_STR
       "RIPng configuration\n"
       "Debug option set for ripng events\n")
{
  ripng_debug_event = RIPNG_DEBUG_EVENT;
  return CMD_WARNING;
}

DEFUN (debug_ripng_packet,
       debug_ripng_packet_cmd,
       "debug ripng packet",
       DEBUG_STR
       "RIPng configuration\n"
       "Debug option set for ripng packet\n")
{
  ripng_debug_packet = RIPNG_DEBUG_PACKET;
  ripng_debug_packet |= RIPNG_DEBUG_SEND;
  ripng_debug_packet |= RIPNG_DEBUG_RECV;
  return CMD_SUCCESS;
}

DEFUN (debug_ripng_packet_direct,
       debug_ripng_packet_direct_cmd,
       "debug ripng packet (recv|send)",
       DEBUG_STR
       "RIPng configuration\n"
       "Debug option set for ripng packet\n"
       "Debug option set for receive packet\n"
       "Debug option set for send packet\n")
{
  ripng_debug_packet |= RIPNG_DEBUG_PACKET;
  if (strncmp ("send", argv[0], strlen (argv[0])) == 0)
    ripng_debug_packet |= RIPNG_DEBUG_SEND;
  if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
    ripng_debug_packet |= RIPNG_DEBUG_RECV;

  return CMD_SUCCESS;
}

/* N.B. the "detail" modifier is a no-op.  we leave this command
   for legacy compatibility. */
DEFUN_DEPRECATED (debug_ripng_packet_detail,
       debug_ripng_packet_detail_cmd,
       "debug ripng packet (recv|send) detail",
       DEBUG_STR
       "RIPng configuration\n"
       "Debug option set for ripng packet\n"
       "Debug option set for receive packet\n"
       "Debug option set for send packet\n"
       "Debug option set detaied information\n")
{
  ripng_debug_packet |= RIPNG_DEBUG_PACKET;
  if (strncmp ("send", argv[0], strlen (argv[0])) == 0)
    ripng_debug_packet |= RIPNG_DEBUG_SEND;
  if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
    ripng_debug_packet |= RIPNG_DEBUG_RECV;

  return CMD_SUCCESS;
}

DEFUN (debug_ripng_zebra,
       debug_ripng_zebra_cmd,
       "debug ripng zebra",
       DEBUG_STR
       "RIPng configuration\n"
       "Debug option set for ripng and zebra communication\n")
{
  ripng_debug_zebra = RIPNG_DEBUG_ZEBRA;
  return CMD_WARNING;
}

DEFUN (no_debug_ripng_events,
       no_debug_ripng_events_cmd,
       "no debug ripng events",
       NO_STR
       DEBUG_STR
       "RIPng configuration\n"
       "Debug option set for ripng events\n")
{
  ripng_debug_event = 0;
  return CMD_SUCCESS;
}

DEFUN (no_debug_ripng_packet,
       no_debug_ripng_packet_cmd,
       "no debug ripng packet",
       NO_STR
       DEBUG_STR
       "RIPng configuration\n"
       "Debug option set for ripng packet\n")
{
  ripng_debug_packet = 0;
  return CMD_SUCCESS;
}

DEFUN (no_debug_ripng_packet_direct,
       no_debug_ripng_packet_direct_cmd,
       "no debug ripng packet (recv|send)",
       NO_STR
       DEBUG_STR
       "RIPng configuration\n"
       "Debug option set for ripng packet\n"
       "Debug option set for receive packet\n"
       "Debug option set for send packet\n")
{
  if (strncmp ("send", argv[0], strlen (argv[0])) == 0)
    {
      if (IS_RIPNG_DEBUG_RECV)
       ripng_debug_packet &= ~RIPNG_DEBUG_SEND;
      else
       ripng_debug_packet = 0;
    }
  else if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
    {
      if (IS_RIPNG_DEBUG_SEND)
       ripng_debug_packet &= ~RIPNG_DEBUG_RECV;
      else
       ripng_debug_packet = 0;
    }
  return CMD_SUCCESS;
}

DEFUN (no_debug_ripng_zebra,
       no_debug_ripng_zebra_cmd,
       "no debug ripng zebra",
       NO_STR
       DEBUG_STR
       "RIPng configuration\n"
       "Debug option set for ripng and zebra communication\n")
{
  ripng_debug_zebra = 0;
  return CMD_WARNING;
}

/* Debug node. */
static struct cmd_node debug_node =
{
  DEBUG_NODE,
  "",				/* Debug node has no interface. */
  1 /* VTYSH */
};

static int
config_write_debug (struct vty *vty)
{
  int write = 0;

  if (IS_RIPNG_DEBUG_EVENT)
    {
      vty_out (vty, "debug ripng events%s", VTY_NEWLINE);
      write++;
    }
  if (IS_RIPNG_DEBUG_PACKET)
    {
      if (IS_RIPNG_DEBUG_SEND && IS_RIPNG_DEBUG_RECV)
	{
	  vty_out (vty, "debug ripng packet%s",
		   VTY_NEWLINE);
	  write++;
	}
      else
	{
	  if (IS_RIPNG_DEBUG_SEND)
	    vty_out (vty, "debug ripng packet send%s",
		     VTY_NEWLINE);
	  else
	    vty_out (vty, "debug ripng packet recv%s",
		     VTY_NEWLINE);
	  write++;
	}
    }
  if (IS_RIPNG_DEBUG_ZEBRA)
    {
      vty_out (vty, "debug ripng zebra%s", VTY_NEWLINE);
      write++;
    }
  return write;
}

void
ripng_debug_reset ()
{
  ripng_debug_event = 0;
  ripng_debug_packet = 0;
  ripng_debug_zebra = 0;
}

void
ripng_debug_init ()
{
  ripng_debug_event = 0;
  ripng_debug_packet = 0;
  ripng_debug_zebra = 0;

  install_node (&debug_node, config_write_debug);

  install_element (VIEW_NODE, &show_debugging_ripng_cmd);

  install_element (ENABLE_NODE, &show_debugging_ripng_cmd);
  install_element (ENABLE_NODE, &debug_ripng_events_cmd);
  install_element (ENABLE_NODE, &debug_ripng_packet_cmd);
  install_element (ENABLE_NODE, &debug_ripng_packet_direct_cmd);
  install_element (ENABLE_NODE, &debug_ripng_packet_detail_cmd);
  install_element (ENABLE_NODE, &debug_ripng_zebra_cmd);
  install_element (ENABLE_NODE, &no_debug_ripng_events_cmd);
  install_element (ENABLE_NODE, &no_debug_ripng_packet_cmd);
  install_element (ENABLE_NODE, &no_debug_ripng_packet_direct_cmd);
  install_element (ENABLE_NODE, &no_debug_ripng_zebra_cmd);

  install_element (CONFIG_NODE, &debug_ripng_events_cmd);
  install_element (CONFIG_NODE, &debug_ripng_packet_cmd);
  install_element (CONFIG_NODE, &debug_ripng_packet_direct_cmd);
  install_element (CONFIG_NODE, &debug_ripng_packet_detail_cmd);
  install_element (CONFIG_NODE, &debug_ripng_zebra_cmd);
  install_element (CONFIG_NODE, &no_debug_ripng_events_cmd);
  install_element (CONFIG_NODE, &no_debug_ripng_packet_cmd);
  install_element (CONFIG_NODE, &no_debug_ripng_packet_direct_cmd);
  install_element (CONFIG_NODE, &no_debug_ripng_zebra_cmd);
}
