// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SHILL_NETLINK_ATTRIBUTE_H_
#define SHILL_NETLINK_ATTRIBUTE_H_

#include <netlink/attr.h>

#include <string>
#include <vector>

#include <base/macros.h>

#include "shill/attribute_list.h"
#include "shill/byte_string.h"
#include "shill/logging.h"
#include "shill/refptr_types.h"

struct nlattr;

namespace shill {

// NetlinkAttribute is an abstract base class that describes an attribute in a
// netlink-80211 message.  Child classes are type-specific and will define
// Get*Value and Set*Value methods (where * is the type).  A second-level of
// child classes exist for each individual attribute type.
//
// An attribute has an id (which is really an enumerated value), a data type,
// and a value.  In an nlattr (the underlying format for an attribute in a
// message), the data is stored as a blob without type information; the writer
// and reader of the attribute must agree on the data type.
class NetlinkAttribute {
 public:
  enum Type {
    kTypeU8,
    kTypeU16,
    kTypeU32,
    kTypeU64,
    kTypeFlag,
    kTypeString,
    kTypeNested,
    kTypeRaw,
    kTypeError
  };

  NetlinkAttribute(int id, const char *id_string,
                   Type datatype, const char *datatype_string);
  virtual ~NetlinkAttribute() {}

  // Static factories generate the appropriate attribute object from the
  // raw nlattr data.
  static NetlinkAttribute *NewControlAttributeFromId(int id);
  static NetlinkAttribute *NewNl80211AttributeFromId(int id);

  virtual bool InitFromNlAttr(const nlattr *data);

  // Accessors for the attribute's id and datatype information.
  int id() const { return id_; }
  virtual const char *id_string() const { return id_string_.c_str(); }
  Type datatype() const { return datatype_; }
  const char *datatype_string() const { return datatype_string_; }

  // Accessors.  Return false if request is made on wrong type of attribute.
  virtual bool GetU8Value(uint8_t *value) const;
  virtual bool SetU8Value(uint8_t new_value);

  virtual bool GetU16Value(uint16_t *value) const;
  virtual bool SetU16Value(uint16_t value);

  virtual bool GetU32Value(uint32_t *value) const;
  virtual bool SetU32Value(uint32_t value);

  virtual bool GetU64Value(uint64_t *value) const;
  virtual bool SetU64Value(uint64_t value);

  virtual bool GetFlagValue(bool *value) const;
  virtual bool SetFlagValue(bool value);

  virtual bool GetStringValue(std::string *value) const;
  virtual bool SetStringValue(const std::string value);

  virtual bool GetNestedAttributeList(AttributeListRefPtr *value);
  virtual bool ConstGetNestedAttributeList(
      AttributeListConstRefPtr *value) const;
  virtual bool SetNestedHasAValue();

  virtual bool GetRawValue(ByteString *value) const;
  virtual bool SetRawValue(const ByteString value);

  // Prints the attribute info -- for debugging.
  virtual void Print(int log_level, int indent) const;

  // Fill a string with characters that represents the value of the attribute.
  // If no attribute is found or if the datatype isn't trivially stringizable,
  // this method returns 'false' and |value| remains unchanged.
  virtual bool ToString(std::string *value) const = 0;

  // Writes the raw attribute data to a string.  For debug.
  std::string RawToString() const;

  // Encodes the attribute suitably for the attributes in the payload portion
  // of a netlink message suitable for Sockets::Send.  Return value is empty on
  // failure.
  virtual ByteString Encode() const = 0;

  bool has_a_value() const { return has_a_value_; }

  // Wrappers for libnl parsers.  Needed because, while |nla_get_*| don't
  // change their arguments, these methods don't declare themselves as 'const'.
  static char *NlaGetString(const nlattr *input) {
    return nla_get_string(const_cast<nlattr *>(input));
  }
  static uint8_t NlaGetU8(const nlattr *input) {
    return nla_get_u8(const_cast<nlattr *>(input));
  }
  static uint16_t NlaGetU16(const nlattr *input) {
    return nla_get_u16(const_cast<nlattr *>(input));
  }
  static uint32_t NlaGetU32(const nlattr *input) {
    return nla_get_u32(const_cast<nlattr *>(input));
  }
  static uint64_t NlaGetU64(const nlattr *input) {
    return nla_get_u64(const_cast<nlattr *>(input));
  }

 protected:
  // Builds a string to precede a printout of this attribute.
  std::string HeaderToPrint(int indent) const;

  // Encodes the attribute suitably for the attributes in the payload portion
  // of a netlink message suitable for Sockets::Send.  Return value is empty on
  // failure.
  ByteString EncodeGeneric(const unsigned char *data, size_t num_bytes) const;

  // Attribute data (NOT including the nlattr header) corresponding to the
  // value in any of the child classes.
  ByteString data_;

  // True if a value has been assigned to the attribute; false, otherwise.
  bool has_a_value_;

 private:
  int id_;
  std::string id_string_;
  Type datatype_;
  const char *datatype_string_;

  DISALLOW_COPY_AND_ASSIGN(NetlinkAttribute);
};

class NetlinkU8Attribute : public NetlinkAttribute {
 public:
  static const char kMyTypeString[];
  static const Type kType;
  NetlinkU8Attribute(int id, const char *id_string)
      : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
  virtual bool InitFromNlAttr(const nlattr *data);
  virtual bool GetU8Value(uint8_t *value) const;
  virtual bool SetU8Value(uint8_t new_value);
  virtual bool ToString(std::string *value) const;
  virtual ByteString Encode() const;

 private:
  uint8_t value_;

  DISALLOW_COPY_AND_ASSIGN(NetlinkU8Attribute);
};

class NetlinkU16Attribute : public NetlinkAttribute {
 public:
  static const char kMyTypeString[];
  static const Type kType;
  NetlinkU16Attribute(int id, const char *id_string)
      : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
  virtual bool InitFromNlAttr(const nlattr *data);
  virtual bool GetU16Value(uint16_t *value) const;
  virtual bool SetU16Value(uint16_t new_value);
  virtual bool ToString(std::string *value) const;
  virtual ByteString Encode() const;

 private:
  uint16_t value_;

  DISALLOW_COPY_AND_ASSIGN(NetlinkU16Attribute);
};

class NetlinkU32Attribute : public NetlinkAttribute {
 public:
  static const char kMyTypeString[];
  static const Type kType;
  NetlinkU32Attribute(int id, const char *id_string)
      : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
  virtual bool InitFromNlAttr(const nlattr *data);
  virtual bool GetU32Value(uint32_t *value) const;
  virtual bool SetU32Value(uint32_t new_value);
  virtual bool ToString(std::string *value) const;
  virtual ByteString Encode() const;

 private:
  uint32_t value_;

  DISALLOW_COPY_AND_ASSIGN(NetlinkU32Attribute);
};

class NetlinkU64Attribute : public NetlinkAttribute {
 public:
  static const char kMyTypeString[];
  static const Type kType;
  NetlinkU64Attribute(int id, const char *id_string)
      : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
  virtual bool InitFromNlAttr(const nlattr *data);
  virtual bool GetU64Value(uint64_t *value) const;
  virtual bool SetU64Value(uint64_t new_value);
  virtual bool ToString(std::string *value) const;
  virtual ByteString Encode() const;

 private:
  uint64_t value_;

  DISALLOW_COPY_AND_ASSIGN(NetlinkU64Attribute);
};

class NetlinkFlagAttribute : public NetlinkAttribute {
 public:
  static const char kMyTypeString[];
  static const Type kType;
  NetlinkFlagAttribute(int id, const char *id_string)
      : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
  virtual bool InitFromNlAttr(const nlattr *data);
  virtual bool GetFlagValue(bool *value) const;
  virtual bool SetFlagValue(bool new_value);
  virtual bool ToString(std::string *value) const;
  virtual ByteString Encode() const;

 private:
  bool value_;

  DISALLOW_COPY_AND_ASSIGN(NetlinkFlagAttribute);
};

class NetlinkStringAttribute : public NetlinkAttribute {
 public:
  static const char kMyTypeString[];
  static const Type kType;
  NetlinkStringAttribute(int id, const char *id_string)
      : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
  virtual bool InitFromNlAttr(const nlattr *data);
  virtual bool GetStringValue(std::string *value) const;
  virtual bool SetStringValue(const std::string new_value);
  virtual bool ToString(std::string *value) const;
  virtual ByteString Encode() const;
  std::string value() const { return value_; }
  void set_value(const std::string &value) { value_ = value; }

 private:
  std::string value_;
  DISALLOW_COPY_AND_ASSIGN(NetlinkStringAttribute);
};

// SSID attributes are just string attributes with different output semantics.
class NetlinkSsidAttribute : public NetlinkStringAttribute {
 public:
  NetlinkSsidAttribute(int id, const char *id_string)
      : NetlinkStringAttribute(id, id_string) {}

  // NOTE: |ToString| or |Print| must be used for logging to allow scrubbing.
  virtual bool ToString(std::string *output) const;

 private:
  DISALLOW_COPY_AND_ASSIGN(NetlinkSsidAttribute);
};

class NetlinkNestedAttribute : public NetlinkAttribute {
 public:
  static const char kMyTypeString[];
  static const Type kType;
  NetlinkNestedAttribute(int id, const char *id_string);
  virtual bool InitFromNlAttr(const nlattr *data);
  virtual bool GetNestedAttributeList(AttributeListRefPtr *value);
  virtual bool ConstGetNestedAttributeList(
      AttributeListConstRefPtr *value) const;
  virtual bool SetNestedHasAValue();
  virtual void Print(int log_level, int indent) const;
  virtual bool ToString(std::string *value) const;
  virtual ByteString Encode() const;

 protected:
  // Describes a single nested attribute.  Provides the expected values and
  // type (including further nesting).  Normally, an array of these, one for
  // each attribute at one level of nesting is presented, along with the data
  // to be parsed, to |InitNestedFromNlAttr|.  If the attributes on one level
  // represent an array, a single |NestedData| is provided and |is_array| is
  // set (note that one level of nesting either contains _only_ an array or
  // _no_ array).
  struct NestedData {
    typedef base::Callback<bool (AttributeList *list, size_t id,
                                 const std::string &attribute_name,
                                 ByteString data)> AttributeParser;
    typedef std::vector<NestedData> NestedDataVector;

    NestedData();
    NestedData(uint16_t type, std::string attribute_name, bool is_array);
    NestedData(uint16_t type, std::string attribute_name, bool is_array,
               const AttributeParser &parse_attribute);
    uint16_t type;
    std::string attribute_name;
    NestedDataVector deeper_nesting;
    bool is_array;
    // Closure that overrides the usual parsing of this attribute.  A non-NULL
    // value for |parse_attribute| will cause the software to ignore the other
    // members of the |NestedData| structure.
    AttributeParser parse_attribute;
  };

  NestedData::NestedDataVector nested_template_;

  // Builds an AttributeList (|list|) that contains all of the attriubtes in
  // |const_data|.  |const_data| should point to the enclosing nested attribute
  // header; for the example of the nested attribute NL80211_ATTR_CQM:
  //    nlattr::nla_type: NL80211_ATTR_CQM <-- const_data points here
  //    nlattr::nla_len: 12 bytes
  //      nlattr::nla_type: PKT_LOSS_EVENT (1st and only nested attribute)
  //      nlattr::nla_len: 8 bytes
  //      <data>: 0x32
  // One can assemble (hence, disassemble) a set of child attributes under a
  // nested attribute parent as an array of elements or as a structure.
  //
  // The data is parsed using the expected configuration in |nested_template|.
  // If the code expects an array, it will pass a single template element and
  // mark that as an array.
  static bool InitNestedFromNlAttr(
      AttributeList *list, const NestedData::NestedDataVector &templates,
      const nlattr *const_data);

  static bool ParseNestedArray(
      AttributeList *list, const NestedData &templates,
      const nlattr *const_data);

  static bool ParseNestedStructure(
      AttributeList *list, const NestedData::NestedDataVector &templates,
      const nlattr *const_data);

  // Helper function used by InitNestedFromNlAttr to add a single child
  // attribute to a nested attribute.
  static void AddAttributeToNested(AttributeList *list, uint16_t type, size_t i,
                                   const std::string &attribute_name,
                                   const nlattr &attr,
                                   const NestedData &nested_data);
  AttributeListRefPtr value_;

 private:
  DISALLOW_COPY_AND_ASSIGN(NetlinkNestedAttribute);
};

class NetlinkRawAttribute : public NetlinkAttribute {
 public:
  static const char kMyTypeString[];
  static const Type kType;
  NetlinkRawAttribute(int id, const char *id_string)
      : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
  virtual bool InitFromNlAttr(const nlattr *data);
  // Gets the value of the data (the header is not stored).
  virtual bool GetRawValue(ByteString *value) const;
  // Should set the value of the data (not the attribute header).
  virtual bool SetRawValue(const ByteString value);
  virtual bool ToString(std::string *value) const;
  virtual ByteString Encode() const;

 private:
  DISALLOW_COPY_AND_ASSIGN(NetlinkRawAttribute);
};

class NetlinkAttributeGeneric : public NetlinkRawAttribute {
 public:
  explicit NetlinkAttributeGeneric(int id);
  virtual const char *id_string() const;

 private:
  std::string id_string_;

  DISALLOW_COPY_AND_ASSIGN(NetlinkAttributeGeneric);
};

}  // namespace shill

#endif  // SHILL_NETLINK_ATTRIBUTE_H_
