/*
 * IS-IS Rout(e)ing protocol - isis_csm.c
 *                             IS-IS circuit state machine
 * Copyright (C) 2001,2002    Sampo Saaristo
 *                            Tampere University of Technology      
 *                            Institute of Communications Engineering
 *
 * This program is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU General Public Licenseas 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; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include <zebra.h>

#include "log.h"
#include "memory.h"
#include "if.h"
#include "linklist.h"
#include "command.h"
#include "thread.h"
#include "hash.h"
#include "prefix.h"
#include "stream.h"

#include "isisd/dict.h"
#include "isisd/include-netbsd/iso.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_network.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_adjacency.h"
#include "isisd/isis_dr.h"
#include "isisd/isisd.h"
#include "isisd/isis_csm.h"
#include "isisd/isis_events.h"

extern struct isis *isis;

static const char *csm_statestr[] = {
  "C_STATE_NA",
  "C_STATE_INIT",
  "C_STATE_CONF",
  "C_STATE_UP"
};

#define STATE2STR(S) csm_statestr[S]

static const char *csm_eventstr[] = {
  "NO_STATE",
  "ISIS_ENABLE",
  "IF_UP_FROM_Z",
  "ISIS_DISABLE",
  "IF_DOWN_FROM_Z",
};

#define EVENT2STR(E) csm_eventstr[E]

struct isis_circuit *
isis_csm_state_change (int event, struct isis_circuit *circuit, void *arg)
{
  int old_state;

  old_state = circuit ? circuit->state : C_STATE_NA;
  if (isis->debugs & DEBUG_EVENTS)
    zlog_debug ("CSM_EVENT: %s", EVENT2STR (event));

  switch (old_state)
    {
    case C_STATE_NA:
      if (circuit)
	zlog_warn ("Non-null circuit while state C_STATE_NA");
      assert (circuit == NULL);
      switch (event)
	{
	case ISIS_ENABLE:
	  circuit = isis_circuit_new ();
	  isis_circuit_configure (circuit, (struct isis_area *) arg);
	  circuit->state = C_STATE_CONF;
	  break;
	case IF_UP_FROM_Z:
	  circuit = isis_circuit_new ();
	  isis_circuit_if_add (circuit, (struct interface *) arg);
	  listnode_add (isis->init_circ_list, circuit);
	  circuit->state = C_STATE_INIT;
	  break;
	case ISIS_DISABLE:
	  zlog_warn ("circuit already disabled");
	  break;
	case IF_DOWN_FROM_Z:
	  zlog_warn ("circuit already disconnected");
	  break;
	}
      break;
    case C_STATE_INIT:
      assert (circuit);
      switch (event)
	{
	case ISIS_ENABLE:
	  isis_circuit_configure (circuit, (struct isis_area *) arg);
	  if (isis_circuit_up (circuit) != ISIS_OK)
	    {
	      isis_circuit_deconfigure (circuit, (struct isis_area *) arg);
	      break;
	    }
	  circuit->state = C_STATE_UP;
	  isis_event_circuit_state_change (circuit, circuit->area, 1);
	  listnode_delete (isis->init_circ_list, circuit);
	  break;
	case IF_UP_FROM_Z:
          assert (circuit);
	  zlog_warn ("circuit already connected");
	  break;
	case ISIS_DISABLE:
	  zlog_warn ("circuit already disabled");
	  break;
	case IF_DOWN_FROM_Z:
	  isis_circuit_if_del (circuit, (struct interface *) arg);
	  listnode_delete (isis->init_circ_list, circuit);
	  isis_circuit_del (circuit);
	  circuit = NULL;
	  break;
	}
      break;
    case C_STATE_CONF:
      assert (circuit);
      switch (event)
	{
	case ISIS_ENABLE:
	  zlog_warn ("circuit already enabled");
	  break;
	case IF_UP_FROM_Z:
	  isis_circuit_if_add (circuit, (struct interface *) arg);
	  if (isis_circuit_up (circuit) != ISIS_OK)
	    {
	      zlog_err("Could not bring up %s because of invalid config.",
	               circuit->interface->name);
	      zlog_err("Clearing config for %s. Please re-examine it.",
	               circuit->interface->name);
	      if (circuit->ip_router)
	        {
	          circuit->ip_router = 0;
	          circuit->area->ip_circuits--;
	        }
	      if (circuit->ipv6_router)
	        {
	          circuit->ipv6_router = 0;
	          circuit->area->ipv6_circuits--;
	        }
	      circuit_update_nlpids(circuit);
	      isis_circuit_deconfigure(circuit, circuit->area);
	      listnode_add (isis->init_circ_list, circuit);
	      circuit->state = C_STATE_INIT;
	      break;
	    }
	  circuit->state = C_STATE_UP;
	  isis_event_circuit_state_change (circuit, circuit->area, 1);
	  break;
	case ISIS_DISABLE:
	  isis_circuit_deconfigure (circuit, (struct isis_area *) arg);
	  isis_circuit_del (circuit);
	  circuit = NULL;
	  break;
	case IF_DOWN_FROM_Z:
	  zlog_warn ("circuit already disconnected");
	  break;
	}
      break;
    case C_STATE_UP:
      assert (circuit);
      switch (event)
	{
	case ISIS_ENABLE:
	  zlog_warn ("circuit already configured");
	  break;
	case IF_UP_FROM_Z:
	  zlog_warn ("circuit already connected");
	  break;
	case ISIS_DISABLE:
	  isis_circuit_down (circuit);
	  isis_circuit_deconfigure (circuit, (struct isis_area *) arg);
	  circuit->state = C_STATE_INIT;
	  isis_event_circuit_state_change (circuit,
                                           (struct isis_area *)arg, 0);
	  listnode_add (isis->init_circ_list, circuit);
	  break;
	case IF_DOWN_FROM_Z:
	  isis_circuit_down (circuit);
          isis_circuit_if_del (circuit, (struct interface *) arg);
	  circuit->state = C_STATE_CONF;
	  isis_event_circuit_state_change (circuit, circuit->area, 0);
	  break;
	}
      break;

    default:
      zlog_warn ("Invalid circuit state %d", old_state);
    }

  if (isis->debugs & DEBUG_EVENTS)
    zlog_debug ("CSM_STATE_CHANGE: %s -> %s ", STATE2STR (old_state),
		circuit ? STATE2STR (circuit->state) : STATE2STR (C_STATE_NA));

  return circuit;
}
