#ifndef PGSQL_RESULT_H
#define PGSQL_RESULT_H

#include "Pgsql_IResult.h"
#include "Pgsql_Row.h"
#include "Pgsql_ErrorDetails.h"

namespace Pgsql {

    /** \brief Non-copyable but movable wrapper for a postgresql result.
	 *
	 * This class makes sure the result is removed from memory. It also supplies an iterator for the
	 * rows from the result facilitating also the use of the cpp for each.
	 */
    class Result: public IResult {
	public:
		Result() = default;
		Result(PGresult *result);
		~Result();

		Result(const Result &rhs) = delete;
		Result& operator=(const Result &rhs) = delete;

		Result(Result &&rhs);
		Result& operator=(Result &&rhs);

        virtual operator bool() const override;

		ExecStatusType resultStatus();

		std::string getResStatus();

		/** Use this to retrieve an error code when this is an error result
		 *
		 * The possible code are listed in https://www.postgresql.org/docs/9.5/static/errcodes-appendix.html
		 */
		std::string diagSqlState();
		/** Retrieves all the error fields. */
		ErrorDetails diagDetails();

        int tuplesAffected() const override;
        int rows() const override;
        int cols() const override;

        const char* getColName(int idx) const override;

        const char* val(int col, int row) const override;
        Value get(int col, int row) const override;
        Oid type(int col) const override;
        bool null(int col, int row) const override;

		/// Return the oid of the table this is a column of
		/// when the column isn't a table column InvalidOid is returned
		/// when col is out of range a std::range_error is thrown
		Oid ftable(int col) const;
		/// Returns the attnum of col in its table, attnum is negative for system cols like oid
		/// It is positive for user columns, 0 signals there is no direct table column mapping
		/// when col is out of range a std::range_error is thrown
		int ftableCol(int col) const;


	//		iterator begin();
	private:
		PGresult *result = nullptr;

		void colRangeCheck(int col) const;
		void rowRangeCheck(int row) const;
	};


} // end namespace Pgsql


#endif // PGSQL_RESULT_H
