//
//  ShardokException.hpp
//  eagle0
//
//  Created by Dan Crosby on 6/17/17.
//  Copyright © 2017 none. All rights reserved.
//

#ifndef ShardokException_h
#define ShardokException_h

#include <exception>
#include <string>
#include <utility>

namespace shardok {
using std::string;

class ShardokException : public std::exception {
protected:
    string description;
    explicit ShardokException(string desc) : description(std::move(desc)){};

public:
    [[nodiscard]] auto what() const noexcept -> const char* override {
        return description.c_str();
    };
};

// Thrown when the client has provided us with bad info. The game state should still be OK.
class ShardokClientErrorException : public ShardokException {
public:
    explicit ShardokClientErrorException(const string& desc) : ShardokException(desc) {}
};

// Thrown when we have some bad internal state. Probably not recoverable.
class ShardokInternalErrorException : public ShardokException {
public:
    explicit ShardokInternalErrorException(const string& desc) : ShardokException(desc) {}
};

static inline void internalAssert(const bool condition) {
    if (!condition) { throw ShardokInternalErrorException("Internal assertion failed"); }
}

static inline void internalAssert(const bool condition, const std::string& message) {
    if (!condition) { throw ShardokInternalErrorException(message); }
}

class ShardokNotImplementedException : public ShardokException {
public:
    explicit ShardokNotImplementedException(const string& operation)
        : ShardokException("Operation " + operation + " is not yet implemented.") {}
};

class ShardokEagleInterfaceException : public ShardokException {
public:
    explicit ShardokEagleInterfaceException(const string& desc) : ShardokException(desc) {}
};
}  // namespace shardok

#endif /* ShardokException_h */
