/*
 * Copyright (c) 2020-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 "graph_edsr.h"

#include "arm_compute/graph/Utils.h"

#include "support/ToolchainSupport.h"
#include "utils/CommonGraphOptions.h"
#include "utils/Utils.h"

using namespace arm_compute::graph;
using namespace arm_compute::utils;

class GraphEdsrExample : public Example
{
public:
    GraphEdsrExample() : cmd_parser(), common_opts(cmd_parser), common_params()
    {
        expected_output_filename = cmd_parser.add_option<SimpleOption<std::string>>("expected-output-filename", "");
        expected_output_filename->set_help(
            "Name of npy file containing the expected output to validate the graph output.");
    }

    GraphEdsrExample(const GraphEdsrExample &)            = delete;
    GraphEdsrExample &operator=(const GraphEdsrExample &) = delete;
    ~GraphEdsrExample() override                          = default;

    bool do_setup(int argc, char **argv) override
    {
        // Parse arguments
        cmd_parser.parse(argc, argv);
        cmd_parser.validate();

        // Consume common parameters
        common_params = consume_common_graph_parameters(common_opts);

        // Return when help menu is requested
        if (common_params.help)
        {
            cmd_parser.print_help(argv[0]);
            return false;
        }

        ARM_COMPUTE_EXIT_ON_MSG(common_params.data_type != DataType::QASYMM8,
                                "Only QASYMM8 is supported for this graph example");

        // Print parameter values
        std::cout << common_params << std::endl;

        model.setup(common_params, *expected_output_filename);

        GraphConfig config;
        config.num_threads = common_params.threads;
        config.use_tuner   = common_params.enable_tuner;
        config.tuner_mode  = common_params.tuner_mode;
        config.tuner_file  = common_params.tuner_file;
        config.mlgo_file   = common_params.mlgo_file;

        context.set_config(config);

        auto pass_manager = create_default_pass_manager(common_params.target, config);
        manager.finalize_graph(model.graph(), context, pass_manager, common_params.target);

        return true;
    }

    void do_run() override
    {
        manager.execute_graph(model.graph());
    }

private:
    CommandLineParser  cmd_parser;
    CommonGraphOptions common_opts;
    CommonGraphParams  common_params;

    GraphContext context{};
    GraphManager manager{};

    SimpleOption<std::string> *expected_output_filename{nullptr};

    GraphEdsr model{};
};

/** Internal implementation of UINT8 EDSR with some modifications from the paper.
 * The sub-pixel convolution has been replaced with a deconvolution layer. This
 * operation is mathematically the same.
 *
 * Convolution replaced by deconvolution:
 *      https://arxiv.org/abs/1609.07009
 *      "Is the deconvolution layer the same as a convolutional layer?"
 *      Wenzhe Shi, Jose Caballero, Lucas Theis, Ferenc Huszar, Andrew Aitken, Christian Ledig, Zehan Wang
 *
 * Original model is:
 *      https://arxiv.org/abs/1707.02921
 *      "Enhanced Deep Residual Networks for Single Image Super-Resolution"
 *      Bee Lim, Sanghyun Son, Heewon Kim, Seungjun Nah, Kyoung Mu Lee
 *
 * @note To list all the possible arguments execute the binary appended with the --help option
 *
 * @param[in] argc Number of arguments
 * @param[in] argv Arguments
 *
 * @return Return code
 */
int main(int argc, char **argv)
{
    return run_example<GraphEdsrExample>(argc, argv);
}
