/*
 * Copyright (c) 2017 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __VOM_PREFIX_H__
#define __VOM_PREFIX_H__

#include <boost/asio/ip/address.hpp>

#include "vom/enum_base.hpp"

namespace VOM {
/**
 * Types belonging to Routing
 */

/**
 * An L3 protocol can be used to construct a prefix that is used
 * to match packets are part of a route.
 */
class l3_proto_t : public enum_base<l3_proto_t>
{
public:
  const static l3_proto_t IPV4;
  const static l3_proto_t IPV6;
  const static l3_proto_t MPLS;

  bool is_ipv4();
  bool is_ipv6();

  static const l3_proto_t& from_address(const boost::asio::ip::address& addr);

private:
  /**
   * Private constructor taking the value and the string name
   */
  l3_proto_t(int v, const std::string& s);
};

/**
 * A next-hop protocol describes the protocol of a peer to which packets
 * are sent after matching a route.
 */
class nh_proto_t : public enum_base<nh_proto_t>
{
public:
  const static nh_proto_t IPV4;
  const static nh_proto_t IPV6;
  const static nh_proto_t MPLS;
  const static nh_proto_t ETHERNET;

  static const nh_proto_t& from_address(const boost::asio::ip::address& addr);

private:
  /**
   * Private constructor taking the value and the string name
   */
  nh_proto_t(int v, const std::string& s);
};

namespace route {
/**
 * type def the table-id
 */
typedef uint32_t table_id_t;

/**
 * The table-id for the default table
 */
const static table_id_t DEFAULT_TABLE = 0;

/**
 * A prefix defintion. Address + length
 */
class prefix_t
{
public:
  /**
   * Default Constructor - creates ::/0
   */
  prefix_t();
  /**
   * Constructor with address and length
   */
  prefix_t(const boost::asio::ip::address& addr, uint8_t len);
  /**
   * Constructor with just the address, this creates a
   * host prefix
   */
  prefix_t(const boost::asio::ip::address& addr);

  /**
   * Constructor with string and length
   */
  prefix_t(const std::string& s, uint8_t len);
  /**
   * Copy Constructor
   */
  prefix_t(const prefix_t&);
  /**
   * Constructor with VPP API prefix representation
   */
  prefix_t(uint8_t is_ip6, uint8_t* addr, uint8_t len);
  /**
   * Destructor
   */
  ~prefix_t();

  /**
   * Get the address
   */
  const boost::asio::ip::address& address() const;

  /**
   * Get the network mask width
   */
  uint8_t mask_width() const;

  /**
   * Assignement
   */
  prefix_t& operator=(const prefix_t&);

  /**
   * Less than operator
   */
  bool operator<(const prefix_t& o) const;

  /**
   * equals operator
   */
  bool operator==(const prefix_t& o) const;

  /**
   * not equal opartor
   */
  bool operator!=(const prefix_t& o) const;

  /**
   * convert to string format for debug purposes
   */
  std::string to_string() const;

  /**
   * The all Zeros prefix
   */
  const static prefix_t ZERO;

  /**
   * The all Zeros v6 prefix
   */
  const static prefix_t ZEROv6;

  /**
   * Convert the prefix into VPP API parameters
   */
  void to_vpp(uint8_t* is_ip6, uint8_t* addr, uint8_t* len) const;

  /**
   * Return a address representation of the mask, e.g. 255.255.0.0
   */
  boost::asio::ip::address mask() const;

  /**
   * get the lowest address in the prefix
   */
  prefix_t low() const;

  /**
   * Get the highest address in the prefix
   */
  prefix_t high() const;

  /**
   * Get the L3 protocol
   */
  l3_proto_t l3_proto() const;

private:
  /**
   * The address
   */
  boost::asio::ip::address m_addr;

  /**
   * The prefix length
   */
  uint8_t m_len;
};
};

boost::asio::ip::address_v4 operator|(const boost::asio::ip::address_v4& addr1,
                                      const boost::asio::ip::address_v4& addr2);

boost::asio::ip::address_v4 operator&(const boost::asio::ip::address_v4& addr1,
                                      const boost::asio::ip::address_v4& addr2);

boost::asio::ip::address_v4 operator~(const boost::asio::ip::address_v4& addr1);

boost::asio::ip::address_v6 operator|(const boost::asio::ip::address_v6& addr1,
                                      const boost::asio::ip::address_v6& addr2);

boost::asio::ip::address_v6 operator&(const boost::asio::ip::address_v6& addr1,
                                      const boost::asio::ip::address_v6& addr2);

boost::asio::ip::address_v6 operator~(const boost::asio::ip::address_v6& addr1);

boost::asio::ip::address operator|(const boost::asio::ip::address& addr1,
                                   const boost::asio::ip::address& addr2);

boost::asio::ip::address operator&(const boost::asio::ip::address& addr1,
                                   const boost::asio::ip::address& addr2);

boost::asio::ip::address operator~(const boost::asio::ip::address& addr1);

/**
 * Ostream printer for prefix_t
 */
std::ostream& operator<<(std::ostream& os, const route::prefix_t& pfx);

/**
 * Convert a boost address into a VPP bytes string
 */
void to_bytes(const boost::asio::ip::address& addr,
              uint8_t* is_ip6,
              uint8_t* array);
void to_bytes(const boost::asio::ip::address_v4& addr, uint8_t* array);
void to_bytes(const boost::asio::ip::address_v6& addr, uint8_t* array);

/**
 * Get the prefix mask length of a host route from the boost address
 */
uint32_t mask_width(const boost::asio::ip::address& addr);

/**
 * Convert a VPP byte stinrg into a boost addresss
 */
boost::asio::ip::address from_bytes(uint8_t is_ip6, uint8_t* array);
};

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "mozilla")
 * End:
 */

#endif
