/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Autogenerated by Thrift Compiler (0.9.3)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
#ifndef airavata_errors_TYPES_H
#define airavata_errors_TYPES_H

#include <iosfwd>

#include <thrift/Thrift.h>
#include <thrift/TApplicationException.h>
#include <thrift/protocol/TProtocol.h>
#include <thrift/transport/TTransport.h>

#include <thrift/cxxfunctional.h>
#include "experiment_model_types.h"


namespace apache { namespace airavata { namespace api { namespace error {

struct AiravataErrorType {
  enum type {
    UNKNOWN = 0,
    PERMISSION_DENIED = 1,
    INTERNAL_ERROR = 2,
    AUTHENTICATION_FAILURE = 3,
    INVALID_AUTHORIZATION = 4,
    AUTHORIZATION_EXPIRED = 5,
    UNKNOWN_GATEWAY_ID = 6,
    UNSUPPORTED_OPERATION = 7
  };
};

extern const std::map<int, const char*> _AiravataErrorType_VALUES_TO_NAMES;

class ExperimentNotFoundException;

class ProjectNotFoundException;

class InvalidRequestException;

class TimedOutException;

class AuthenticationException;

class AuthorizationException;

class AiravataClientException;

class ValidatorResult;

class ValidationResults;

class LaunchValidationException;

class AiravataSystemException;

class DataManagerServiceException;


class ExperimentNotFoundException : public ::apache::thrift::TException {
 public:

  ExperimentNotFoundException(const ExperimentNotFoundException&);
  ExperimentNotFoundException& operator=(const ExperimentNotFoundException&);
  ExperimentNotFoundException() : message() {
  }

  virtual ~ExperimentNotFoundException() throw();
  std::string message;

  void __set_message(const std::string& val);

  bool operator == (const ExperimentNotFoundException & rhs) const
  {
    if (!(message == rhs.message))
      return false;
    return true;
  }
  bool operator != (const ExperimentNotFoundException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ExperimentNotFoundException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(ExperimentNotFoundException &a, ExperimentNotFoundException &b);

inline std::ostream& operator<<(std::ostream& out, const ExperimentNotFoundException& obj)
{
  obj.printTo(out);
  return out;
}


class ProjectNotFoundException : public ::apache::thrift::TException {
 public:

  ProjectNotFoundException(const ProjectNotFoundException&);
  ProjectNotFoundException& operator=(const ProjectNotFoundException&);
  ProjectNotFoundException() : message() {
  }

  virtual ~ProjectNotFoundException() throw();
  std::string message;

  void __set_message(const std::string& val);

  bool operator == (const ProjectNotFoundException & rhs) const
  {
    if (!(message == rhs.message))
      return false;
    return true;
  }
  bool operator != (const ProjectNotFoundException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ProjectNotFoundException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(ProjectNotFoundException &a, ProjectNotFoundException &b);

inline std::ostream& operator<<(std::ostream& out, const ProjectNotFoundException& obj)
{
  obj.printTo(out);
  return out;
}


class InvalidRequestException : public ::apache::thrift::TException {
 public:

  InvalidRequestException(const InvalidRequestException&);
  InvalidRequestException& operator=(const InvalidRequestException&);
  InvalidRequestException() : message() {
  }

  virtual ~InvalidRequestException() throw();
  std::string message;

  void __set_message(const std::string& val);

  bool operator == (const InvalidRequestException & rhs) const
  {
    if (!(message == rhs.message))
      return false;
    return true;
  }
  bool operator != (const InvalidRequestException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const InvalidRequestException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(InvalidRequestException &a, InvalidRequestException &b);

inline std::ostream& operator<<(std::ostream& out, const InvalidRequestException& obj)
{
  obj.printTo(out);
  return out;
}


class TimedOutException : public ::apache::thrift::TException {
 public:

  TimedOutException(const TimedOutException&);
  TimedOutException& operator=(const TimedOutException&);
  TimedOutException() {
  }

  virtual ~TimedOutException() throw();

  bool operator == (const TimedOutException & /* rhs */) const
  {
    return true;
  }
  bool operator != (const TimedOutException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const TimedOutException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(TimedOutException &a, TimedOutException &b);

inline std::ostream& operator<<(std::ostream& out, const TimedOutException& obj)
{
  obj.printTo(out);
  return out;
}


class AuthenticationException : public ::apache::thrift::TException {
 public:

  AuthenticationException(const AuthenticationException&);
  AuthenticationException& operator=(const AuthenticationException&);
  AuthenticationException() : message() {
  }

  virtual ~AuthenticationException() throw();
  std::string message;

  void __set_message(const std::string& val);

  bool operator == (const AuthenticationException & rhs) const
  {
    if (!(message == rhs.message))
      return false;
    return true;
  }
  bool operator != (const AuthenticationException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AuthenticationException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(AuthenticationException &a, AuthenticationException &b);

inline std::ostream& operator<<(std::ostream& out, const AuthenticationException& obj)
{
  obj.printTo(out);
  return out;
}


class AuthorizationException : public ::apache::thrift::TException {
 public:

  AuthorizationException(const AuthorizationException&);
  AuthorizationException& operator=(const AuthorizationException&);
  AuthorizationException() : message() {
  }

  virtual ~AuthorizationException() throw();
  std::string message;

  void __set_message(const std::string& val);

  bool operator == (const AuthorizationException & rhs) const
  {
    if (!(message == rhs.message))
      return false;
    return true;
  }
  bool operator != (const AuthorizationException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AuthorizationException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(AuthorizationException &a, AuthorizationException &b);

inline std::ostream& operator<<(std::ostream& out, const AuthorizationException& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _AiravataClientException__isset {
  _AiravataClientException__isset() : parameter(false) {}
  bool parameter :1;
} _AiravataClientException__isset;

class AiravataClientException : public ::apache::thrift::TException {
 public:

  AiravataClientException(const AiravataClientException&);
  AiravataClientException& operator=(const AiravataClientException&);
  AiravataClientException() : airavataErrorType((AiravataErrorType::type)0), parameter() {
  }

  virtual ~AiravataClientException() throw();
  AiravataErrorType::type airavataErrorType;
  std::string parameter;

  _AiravataClientException__isset __isset;

  void __set_airavataErrorType(const AiravataErrorType::type val);

  void __set_parameter(const std::string& val);

  bool operator == (const AiravataClientException & rhs) const
  {
    if (!(airavataErrorType == rhs.airavataErrorType))
      return false;
    if (__isset.parameter != rhs.__isset.parameter)
      return false;
    else if (__isset.parameter && !(parameter == rhs.parameter))
      return false;
    return true;
  }
  bool operator != (const AiravataClientException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AiravataClientException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(AiravataClientException &a, AiravataClientException &b);

inline std::ostream& operator<<(std::ostream& out, const AiravataClientException& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _ValidatorResult__isset {
  _ValidatorResult__isset() : errorDetails(false) {}
  bool errorDetails :1;
} _ValidatorResult__isset;

class ValidatorResult {
 public:

  ValidatorResult(const ValidatorResult&);
  ValidatorResult& operator=(const ValidatorResult&);
  ValidatorResult() : result(0), errorDetails() {
  }

  virtual ~ValidatorResult() throw();
  bool result;
  std::string errorDetails;

  _ValidatorResult__isset __isset;

  void __set_result(const bool val);

  void __set_errorDetails(const std::string& val);

  bool operator == (const ValidatorResult & rhs) const
  {
    if (!(result == rhs.result))
      return false;
    if (__isset.errorDetails != rhs.__isset.errorDetails)
      return false;
    else if (__isset.errorDetails && !(errorDetails == rhs.errorDetails))
      return false;
    return true;
  }
  bool operator != (const ValidatorResult &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ValidatorResult & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(ValidatorResult &a, ValidatorResult &b);

inline std::ostream& operator<<(std::ostream& out, const ValidatorResult& obj)
{
  obj.printTo(out);
  return out;
}


class ValidationResults {
 public:

  ValidationResults(const ValidationResults&);
  ValidationResults& operator=(const ValidationResults&);
  ValidationResults() : validationState(0) {
  }

  virtual ~ValidationResults() throw();
  bool validationState;
  std::vector<ValidatorResult>  validationResultList;

  void __set_validationState(const bool val);

  void __set_validationResultList(const std::vector<ValidatorResult> & val);

  bool operator == (const ValidationResults & rhs) const
  {
    if (!(validationState == rhs.validationState))
      return false;
    if (!(validationResultList == rhs.validationResultList))
      return false;
    return true;
  }
  bool operator != (const ValidationResults &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ValidationResults & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(ValidationResults &a, ValidationResults &b);

inline std::ostream& operator<<(std::ostream& out, const ValidationResults& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _LaunchValidationException__isset {
  _LaunchValidationException__isset() : errorMessage(false) {}
  bool errorMessage :1;
} _LaunchValidationException__isset;

class LaunchValidationException : public ::apache::thrift::TException {
 public:

  LaunchValidationException(const LaunchValidationException&);
  LaunchValidationException& operator=(const LaunchValidationException&);
  LaunchValidationException() : errorMessage() {
  }

  virtual ~LaunchValidationException() throw();
  ValidationResults validationResult;
  std::string errorMessage;

  _LaunchValidationException__isset __isset;

  void __set_validationResult(const ValidationResults& val);

  void __set_errorMessage(const std::string& val);

  bool operator == (const LaunchValidationException & rhs) const
  {
    if (!(validationResult == rhs.validationResult))
      return false;
    if (__isset.errorMessage != rhs.__isset.errorMessage)
      return false;
    else if (__isset.errorMessage && !(errorMessage == rhs.errorMessage))
      return false;
    return true;
  }
  bool operator != (const LaunchValidationException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const LaunchValidationException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(LaunchValidationException &a, LaunchValidationException &b);

inline std::ostream& operator<<(std::ostream& out, const LaunchValidationException& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _AiravataSystemException__isset {
  _AiravataSystemException__isset() : message(false) {}
  bool message :1;
} _AiravataSystemException__isset;

class AiravataSystemException : public ::apache::thrift::TException {
 public:

  AiravataSystemException(const AiravataSystemException&);
  AiravataSystemException& operator=(const AiravataSystemException&);
  AiravataSystemException() : airavataErrorType((AiravataErrorType::type)0), message() {
  }

  virtual ~AiravataSystemException() throw();
  AiravataErrorType::type airavataErrorType;
  std::string message;

  _AiravataSystemException__isset __isset;

  void __set_airavataErrorType(const AiravataErrorType::type val);

  void __set_message(const std::string& val);

  bool operator == (const AiravataSystemException & rhs) const
  {
    if (!(airavataErrorType == rhs.airavataErrorType))
      return false;
    if (__isset.message != rhs.__isset.message)
      return false;
    else if (__isset.message && !(message == rhs.message))
      return false;
    return true;
  }
  bool operator != (const AiravataSystemException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AiravataSystemException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(AiravataSystemException &a, AiravataSystemException &b);

inline std::ostream& operator<<(std::ostream& out, const AiravataSystemException& obj)
{
  obj.printTo(out);
  return out;
}


class DataManagerServiceException : public ::apache::thrift::TException {
 public:

  DataManagerServiceException(const DataManagerServiceException&);
  DataManagerServiceException& operator=(const DataManagerServiceException&);
  DataManagerServiceException() : message() {
  }

  virtual ~DataManagerServiceException() throw();
  std::string message;

  void __set_message(const std::string& val);

  bool operator == (const DataManagerServiceException & rhs) const
  {
    if (!(message == rhs.message))
      return false;
    return true;
  }
  bool operator != (const DataManagerServiceException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const DataManagerServiceException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(DataManagerServiceException &a, DataManagerServiceException &b);

inline std::ostream& operator<<(std::ostream& out, const DataManagerServiceException& obj)
{
  obj.printTo(out);
  return out;
}

}}}} // namespace

#endif
