// Copyright 2018 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_NET_ATTRIBUTE_LIST_H_
#define SHILL_NET_ATTRIBUTE_LIST_H_

#include <linux/nl80211.h>

#include <map>
#include <memory>
#include <string>

#include <base/bind.h>

#include "shill/net/netlink_message.h"
#include "shill/net/shill_export.h"

namespace shill {

class AttributeList;
using AttributeListConstRefPtr = scoped_refptr<const AttributeList>;
using AttributeListRefPtr = scoped_refptr<AttributeList>;

class ByteString;
class NetlinkAttribute;

class SHILL_EXPORT AttributeList : public base::RefCounted<AttributeList> {
 public:
  using NewFromIdMethod =
      base::Callback<std::unique_ptr<NetlinkAttribute>(int id)>;
  using AttributeMethod = base::Callback<bool(int id, const ByteString& value)>;

  AttributeList();

  // Instantiates an NetlinkAttribute of the appropriate type from |id|,
  // and adds it to |attributes_|.
  bool CreateAttribute(int id, NewFromIdMethod factory);

  // Helper function for creating control attribute.
  bool CreateControlAttribute(int id);

  // Helper function for creating nl80211 attribute.
  bool CreateNl80211Attribute(int id, NetlinkMessage::MessageContext context);

  // Instantiates an NetlinkAttribute of the appropriate type from |id|
  // using |factory|, initializes it from |value|, and adds it to |attributes_|.
  bool CreateAndInitAttribute(const NewFromIdMethod& factory,
                              int id, const ByteString& value);

  // Initializes the attribute |id| from the data in |value|.
  bool InitAttributeFromValue(int id, const ByteString& value);

  // Prints the attribute list with each attribute using no less than 1 line.
  // |indent| indicates the amout of leading spaces to be printed (useful for
  // nested attributes).
  void Print(int log_level, int indent) const;

  // Visit each attribute in |payload| starting at |offset|.  Call |method|
  // for each attribute.  If |method| returns false, the travesal is terminated
  // and false is returned.  If a malformed attribute entry is encountered,
  // this method also returns false.
  static bool IterateAttributes(const ByteString& payload, size_t offset,
                                const AttributeMethod& method);

  // Decode an attribute list starting from |offset| within |payload|.  Use
  // |factory| to create each attribute object.
  bool Decode(const ByteString& payload,
              size_t offset, const NewFromIdMethod& factory);

  // Returns the attributes as the payload portion of a netlink message
  // suitable for Sockets::Send.  Return value is empty on failure (or if no
  // attributes exist).
  ByteString Encode() const;

  // Create, get, and set attributes of the given types.  Attributes are
  // accessed via an integer |id|.  |id_string| is a string used to describe
  // the attribute in debug output.
  bool CreateU8Attribute(int id, const char* id_string);
  bool SetU8AttributeValue(int id, uint8_t value);
  bool GetU8AttributeValue(int id, uint8_t* value) const;

  bool CreateU16Attribute(int id, const char* id_string);
  bool SetU16AttributeValue(int id, uint16_t value);
  bool GetU16AttributeValue(int id, uint16_t* value) const;

  bool CreateU32Attribute(int id, const char* id_string);
  bool SetU32AttributeValue(int id, uint32_t value);
  bool GetU32AttributeValue(int id, uint32_t* value) const;

  bool CreateU64Attribute(int id, const char* id_string);
  bool SetU64AttributeValue(int id, uint64_t value);
  bool GetU64AttributeValue(int id, uint64_t* value) const;

  bool CreateFlagAttribute(int id, const char* id_string);
  bool SetFlagAttributeValue(int id, bool value);
  bool GetFlagAttributeValue(int id, bool* value) const;
  // |IsFlagAttributeTrue| returns true if the flag attribute |id| is true.  It
  // retruns false if the attribute does not exist, is not of type kTypeFlag,
  // or is not true.
  bool IsFlagAttributeTrue(int id) const;

  bool CreateStringAttribute(int id, const char* id_string);
  // SSID attributes are derived from string attributes.
  bool CreateSsidAttribute(int id, const char* id_string);
  bool SetStringAttributeValue(int id, const std::string& value);
  bool GetStringAttributeValue(int id, std::string* value) const;

  bool CreateNestedAttribute(int id, const char* id_string);
  bool SetNestedAttributeHasAValue(int id);
  bool GetNestedAttributeList(int id, AttributeListRefPtr* value);
  bool ConstGetNestedAttributeList(int id,
                                   AttributeListConstRefPtr* value) const;

  bool CreateRawAttribute(int id, const char* id_string);
  // |value| should point to the data (after the |nlattr| header, if there is
  // one).
  bool SetRawAttributeValue(int id, ByteString value);
  bool GetRawAttributeValue(int id, ByteString* output) const;

  // This retrieves a string from any kind of attribute.
  bool GetAttributeAsString(int id, std::string* value) const;

 protected:
  friend class base::RefCounted<AttributeList>;

  virtual ~AttributeList();

 private:
  friend class AttributeIdIterator;
  friend class NetlinkNestedAttribute;

  using AttributeMap = std::map<int, std::unique_ptr<NetlinkAttribute>>;

  // Using this to get around issues with const and operator[].
  SHILL_PRIVATE NetlinkAttribute* GetAttribute(int id) const;

  AttributeMap attributes_;

  DISALLOW_COPY_AND_ASSIGN(AttributeList);
};

// Provides a mechanism to iterate through the ids of all of the attributes
// in an |AttributeList|.  This class is really only useful if the caller
// knows the type of each attribute in advance (such as with a nested array).
class AttributeIdIterator {
 public:
  explicit AttributeIdIterator(const AttributeList& list)
      : iter_(list.attributes_.begin()),
        end_(list.attributes_.end()) {
  }
  void Advance() { ++iter_; }
  bool AtEnd() const { return iter_ == end_; }
  int GetId() const { return iter_->first; }

 private:
  AttributeList::AttributeMap::const_iterator iter_;
  const AttributeList::AttributeMap::const_iterator end_;

  DISALLOW_COPY_AND_ASSIGN(AttributeIdIterator);
};

}  // namespace shill

#endif  // SHILL_NET_ATTRIBUTE_LIST_H_
