/*
 * Copyright (c) 2017-2019 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_DATASET_MODES
#define ARM_COMPUTE_TEST_DATASET_MODES

#include <istream>
#include <ostream>
#include <sstream>
#include <stdexcept>
#include <string>

namespace arm_compute
{
namespace test
{
namespace framework
{
/** Possible dataset modes. */
enum class DatasetMode : unsigned int
{
    ALL       = ~0U,
    DISABLED  = 0,
    PRECOMMIT = 1,
    NIGHTLY   = 2
};

inline DatasetMode operator&(DatasetMode t1, DatasetMode t2)
{
    using type = std::underlying_type<DatasetMode>::type;
    return static_cast<DatasetMode>(static_cast<type>(t1) & static_cast<type>(t2));
}

inline DatasetMode operator|(DatasetMode t1, DatasetMode t2)
{
    using type = std::underlying_type<DatasetMode>::type;
    return static_cast<DatasetMode>(static_cast<type>(t1) | static_cast<type>(t2));
}

inline DatasetMode &operator|=(DatasetMode &t1, DatasetMode t2)
{
    using type = std::underlying_type<DatasetMode>::type;
    t1         = static_cast<DatasetMode>(static_cast<type>(t1) | static_cast<type>(t2));
    return t1;
}

DatasetMode dataset_mode_from_name(const std::string &name);

inline ::std::istream &operator>>(::std::istream &stream, DatasetMode &mode)
{
    std::string value;
    stream >> value;
    mode = dataset_mode_from_name(value);
    return stream;
}

inline ::std::ostream &operator<<(::std::ostream &stream, DatasetMode mode)
{
    switch(mode)
    {
        case DatasetMode::DISABLED:
            stream << "DISABLED";
            break;
        case DatasetMode::PRECOMMIT:
            stream << "PRECOMMIT";
            break;
        case DatasetMode::NIGHTLY:
            stream << "NIGHTLY";
            break;
        case DatasetMode::ALL:
            stream << "ALL";
            break;
        default:
            throw std::invalid_argument("Unsupported dataset mode");
    }

    return stream;
}

inline std::string to_string(DatasetMode mode)
{
    std::stringstream stream;
    stream << mode;
    return stream.str();
}
} // namespace framework
} // namespace test
} // namespace arm_compute
#endif /* ARM_COMPUTE_TEST_DATASET_MODES */
