/*
 * Copyright (c) 2018,2021 Arm Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * 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.
 */
#include "arm_compute/graph/INode.h"

#include "arm_compute/core/Error.h"
#include "arm_compute/graph/Edge.h"
#include "arm_compute/graph/Graph.h"
#include "arm_compute/graph/Tensor.h"

namespace arm_compute
{
namespace graph
{
// *INDENT-OFF*
// clang-format off
INode::INode()
    : _graph(nullptr), _id(EmptyNodeID), _common_params({ "", Target::UNSPECIFIED}),
      _outputs(), _input_edges(), _output_edges(), _assigned_target(Target::UNSPECIFIED)
      ,_post_op_info_list(std::list<std::unique_ptr<ConvPostOpInfo>> {})
{
}
// clang-format on
// *INDENT-ON*

Status INode::validate() const
{
    return Status{};
}

void INode::set_graph(Graph *g)
{
    ARM_COMPUTE_ERROR_ON(g == nullptr);
    _graph = g;
}

void INode::set_id(NodeID id)
{
    _id = id;
}

void INode::set_common_node_parameters(NodeParams common_params)
{
    _common_params = std::move(common_params);
}

void INode::set_requested_target(Target target)
{
    _common_params.target = target;
}

void INode::set_assigned_target(Target target)
{
    _assigned_target = target;
}

void INode::set_output_tensor(TensorID tid, size_t idx)
{
    if(tid != NullTensorID && (idx < _outputs.size()) && (_graph->tensor(tid) != nullptr))
    {
        ARM_COMPUTE_ERROR_ON(_graph == nullptr);
        Tensor *updated_tensor = _graph->tensor(tid);
        _outputs[idx]          = tid;

        // Set tensor to all output edges of the node
        for(auto &output_edge_id : _output_edges)
        {
            auto output_edge = _graph->edge(output_edge_id);
            if(output_edge != nullptr)
            {
                // Unbind edge from current tensor
                auto current_output_tensor = output_edge->tensor();
                current_output_tensor->unbind_edge(output_edge->id());

                // Update tensor to edge and rebind tensor
                output_edge->update_bound_tensor(updated_tensor);
                updated_tensor->bind_edge(output_edge->id());
            }
        }
    }
}

NodeID INode::id() const
{
    return _id;
}

std::string INode::name() const
{
    return _common_params.name;
}

const Graph *INode::graph() const
{
    return _graph;
}

Graph *INode::graph()
{
    return _graph;
}

const std::vector<TensorID> &INode::outputs() const
{
    return _outputs;
}

const std::vector<EdgeID> &INode::input_edges() const
{
    return _input_edges;
}

const std::set<EdgeID> &INode::output_edges() const
{
    return _output_edges;
}

TensorID INode::input_id(size_t idx) const
{
    ARM_COMPUTE_ERROR_ON(idx >= _input_edges.size());
    Edge *e = _graph->edge(_input_edges[idx]);
    return (e != nullptr) ? e->tensor_id() : NullTensorID;
}

TensorID INode::output_id(size_t idx) const
{
    ARM_COMPUTE_ERROR_ON(idx >= _outputs.size());
    return _outputs[idx];
}

Tensor *INode::input(size_t idx) const
{
    ARM_COMPUTE_ERROR_ON(_graph == nullptr);
    ARM_COMPUTE_ERROR_ON(idx >= _input_edges.size());
    Edge *e = _graph->edge(_input_edges[idx]);
    return (e != nullptr) ? e->tensor() : nullptr;
}

Tensor *INode::output(size_t idx) const
{
    ARM_COMPUTE_ERROR_ON(_graph == nullptr);
    ARM_COMPUTE_ERROR_ON(idx >= _outputs.size());
    return _graph->tensor(_outputs[idx]);
}

EdgeID INode::input_edge_id(size_t idx) const
{
    ARM_COMPUTE_ERROR_ON(idx >= _input_edges.size());
    return _input_edges[idx];
}

Edge *INode::input_edge(size_t idx) const
{
    ARM_COMPUTE_ERROR_ON(_graph == nullptr);
    ARM_COMPUTE_ERROR_ON(idx >= _input_edges.size());
    return _graph->edge(_input_edges[idx]);
}

size_t INode::num_inputs() const
{
    return _input_edges.size();
}

size_t INode::num_outputs() const
{
    return _outputs.size();
}

NodeParams INode::common_node_params() const
{
    return _common_params;
}

Target INode::requested_target() const
{
    return _common_params.target;
}

Target INode::assigned_target() const
{
    return _assigned_target;
}

const std::list<std::unique_ptr<ConvPostOpInfo>> &INode::post_op_info_list() const
{
    return _post_op_info_list;
}

std::list<std::unique_ptr<ConvPostOpInfo>> &INode::post_op_info_list()
{
    return _post_op_info_list;
}
} // namespace graph
} // namespace arm_compute