/*
 * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES
 * Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#pragma once

#include "port_data.h"

class FabricProvider;
class TreeManager;
class CommandManager;
class TreeNode;
class TreeEdge;
class HostInfo;
class PortData;
class SharpJob;
class AggNode;
class AggNodeFabricInfo;
struct SpanningInfo;
struct QPData;

struct HostInfoSort
{
    inline bool operator()(const HostInfo* p_lhs, const HostInfo* p_rhs) const;
};

using SetJobPtr = std::set<SharpJob*>;
using UnorderedSetJobPtr = std::unordered_set<SharpJob*>;
using MapSharpJobIdToTreeIds = std::map<sharp_job_id_t, SetTreeIds>;
using SetTreeNodePtr = std::set<class TreeNode*>;
using SetHostInfoPtr = std::set<const HostInfo*, HostInfoSort>;
using SetHcaPortKey = std::set<hca_port_key_t>;
using ListPortDataPtr = std::list<class PortData*>;
using ListSpanningInfo = std::list<struct SpanningInfo>;
using VecAnFabricInfoPtr = std::vector<class AggNodeFabricInfo*>;
using VecTreeNodePtr = std::vector<class TreeNode*>;
using MapTreeIdToTreeNode = std::unordered_map<sharp_trees_t, class TreeNode*>;
using MapTreeHashToDumpMessage = std::unordered_map<uint64_t, std::string>;
using VecTreeEdge = std::vector<class TreeEdge>;
using VecAggTreePtr = std::vector<class AggTree*>;
using AggTreesIter = VecAggTreePtr::iterator;
using AggTreesConstIter = VecAggTreePtr::const_iterator;

using MapStrListAggNodeFabricPtr = std::map<string, ListAggNodeFabricPtr>;
using MapStrAggNodeFabricPtr = std::map<string, class AggNodeFabricInfo*>;
using MapHcaPortKeyToAggNodeFabrics = std::multimap<hca_port_key_t, class AggNodeFabricInfo*>;
using MapStrToHostInfo = std::map<string, class HostInfo*>;

using MapHcaPortKeyToPortKey = std::map<hca_port_key_t, port_key_t>;
using MapQPNToQPData = std::map<uint32_t, QPData>;
using MapQPNToQPDataIter = MapQPNToQPData::iterator;
using MapHcaPortKeyToPortKeyIter = MapHcaPortKeyToPortKey::iterator;
using MapPortKeyToHCAPortKeys = std::multimap<port_key_t, hca_port_key_t>;
using MapPortKeyToHCAPortKeysIter = MapPortKeyToHCAPortKeys::iterator;

using MapTreeTurns = std::map<std::pair<port_key_t, port_key_t>, uint16_t>;

using MapFileNameToCRC = std::map<string, uint32_t>;
using VecAggPathRecord = std::vector<struct AggPathRecord>;
using ListLids = std::list<lid_t>;
using SetLids = std::set<lid_t>;

// use bits values to enable selecting several states (e.g. configured or error)
enum QpStateEnum
{
    QP_STATE_UNALLOCATED = 1,
    QP_STATE_ALLOCATED = 2,
    QP_STATE_CONFIGURED = 4,
    QP_STATE_ERROR = 8,
    QP_STATE_UNALLOCATE_REQUIRED = 16,
    QP_STATE_UNCONFIGURE_REQUIRED = 32,
    QP_STATE_UNCONFIGURE = (QP_STATE_UNCONFIGURE_REQUIRED | QP_STATE_CONFIGURED)
};

const char* QpStateToStr(QpStateEnum qp_state);

class Qp
{
    uint32_t m_qp_num_;
    QpStateEnum m_qp_state_;

   public:
    Qp();

    inline void SetNumber(const uint32_t qp_number) { m_qp_num_ = qp_number; }
    inline uint32_t GetNumber() const { return m_qp_num_; }
    inline QpStateEnum GetState() const { return m_qp_state_; }
    inline void SetState(const QpStateEnum qp_state) { m_qp_state_ = qp_state; }
    inline void Clear()
    {
        m_qp_num_ = 0;
        m_qp_state_ = QP_STATE_UNALLOCATED;
    }

    void Set(const uint32_t qp_num, const QpStateEnum qp_state, const std::string& fabric_info);
};

struct QPData
{
    uint32_t qpn;
    uint32_t index;
    QpStateEnum state;
    SharpMtu mtu;
    lid_t rlid;
    uint8_t ts;
    uint32_t rqpn;
    bool is_parent;
    sharp_trees_t tree_id;
    uint32_t port;
    bool is_root_qp;
    bool is_multicast_qp;
};
