/*
 * Copyright (c) 2017-2020 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.
 */
#ifndef ARM_COMPUTE_TEST_TEST_CASE_FACTORY
#define ARM_COMPUTE_TEST_TEST_CASE_FACTORY

#include "DatasetModes.h"
#include "TestCase.h"

#include <memory>
#include <string>

namespace arm_compute
{
namespace test
{
namespace framework
{
/** Abstract factory class to create test cases. */
class TestCaseFactory
{
public:
    /** Test case status.
     *
     * ACTIVE == Test is run and result is validated. Failure on failed validation.
     * EXPECTED_FAILURE == Test is run and result is validated. Failure on successful validation.
     * DISABLED == Test is not run.
     */
    enum class Status
    {
        ACTIVE,
        EXPECTED_FAILURE,
        DISABLED
    };

    /** Constructor.
     *
     * @param[in] suite_name  Name of the test suite to which the test case has been added.
     * @param[in] name        Name of the test case.
     * @param[in] mode        Datset mode of the test case.
     * @param[in] status      Status of the test case.
     * @param[in] description Description of data arguments.
     */
    TestCaseFactory(std::string suite_name, std::string name, DatasetMode mode, Status status, std::string description = "");

    /** Default destructor. */
    virtual ~TestCaseFactory() = default;

    /** Name of the test case.
     *
     * @return Name of the test case.
     */
    std::string name() const;

    /** Get the mode for which test case will be enabled.
     *
     * @return Dataset mode of the test case.
     */
    DatasetMode mode() const;

    /** Get the status of the test case.
     *
     * @return Status of the test case.
     */
    Status status() const;

    /** Factory function to create the test case
     *
     * @return Unique pointer to a newly created test case.
     */
    virtual std::unique_ptr<TestCase> make() const = 0;

private:
    const std::string _suite_name;
    const std::string _test_name;
    const std::string _data_description;
    const DatasetMode _mode{ DatasetMode::ALL };
    const Status      _status{ Status::ACTIVE };
};

/** Implementation of a test case factory to create non-data test cases. */
template <typename T>
class SimpleTestCaseFactory final : public TestCaseFactory
{
public:
    /** Default constructor. */
    using TestCaseFactory::TestCaseFactory;

    std::unique_ptr<TestCase> make() const override;
};

/** Implementation of a test case factory to create data test cases. */
template <typename T, typename D>
class DataTestCaseFactory final : public TestCaseFactory
{
public:
    /** Constructor.
     *
     * @param[in] suite_name  Name of the test suite to which the test case has been added.
     * @param[in] test_name   Name of the test case.
     * @param[in] mode        Mode in which the test case is enabled.
     * @param[in] status      Status of the test case.
     * @param[in] description Description of data arguments.
     * @param[in] data        Input data for the test case.
     */
    DataTestCaseFactory(std::string suite_name, std::string test_name, DatasetMode mode, Status status, std::string description, const D &data);

    std::unique_ptr<TestCase> make() const override;

private:
    D _data;
};

inline TestCaseFactory::TestCaseFactory(std::string suite_name, std::string test_name, DatasetMode mode, Status status, std::string description)
    : _suite_name{ std::move(suite_name) }, _test_name{ std::move(test_name) }, _data_description{ std::move(description) }, _mode{ mode }, _status{ status }

{
}

inline std::string TestCaseFactory::name() const
{
    std::string name = _suite_name + "/" + _test_name;

    if(!_data_description.empty())
    {
        name += "@" + _data_description;
    }

    return name;
}

inline DatasetMode TestCaseFactory::mode() const
{
    return _mode;
}

inline TestCaseFactory::Status TestCaseFactory::status() const
{
    return _status;
}

inline ::std::ostream &operator<<(::std::ostream &stream, TestCaseFactory::Status status)
{
    switch(status)
    {
        case TestCaseFactory::Status::ACTIVE:
            stream << "ACTIVE";
            break;
        case TestCaseFactory::Status::EXPECTED_FAILURE:
            stream << "EXPECTED_FAILURE";
            break;
        case TestCaseFactory::Status::DISABLED:
            stream << "DISABLED";
            break;
        default:
            throw std::invalid_argument("Unsupported test case factory status");
    }

    return stream;
}

template <typename T>
inline std::unique_ptr<TestCase> SimpleTestCaseFactory<T>::make() const
{
    return std::make_unique<T>();
}

template <typename T, typename D>
inline DataTestCaseFactory<T, D>::DataTestCaseFactory(std::string suite_name, std::string test_name, DatasetMode mode, Status status, std::string description, const D &data)
    : TestCaseFactory{ std::move(suite_name), std::move(test_name), mode, status, std::move(description) }, _data{ data }
{
}

template <typename T, typename D>
inline std::unique_ptr<TestCase> DataTestCaseFactory<T, D>::make() const
{
    return std::make_unique<T>(_data);
}
} // namespace framework
} // namespace test
} // namespace arm_compute
#endif /* ARM_COMPUTE_TEST_TEST_CASE_FACTORY */
