/*
 * utf8 ru
  *      Author: alexrayne <alexraynepe196@gmail.com>
  ------------------------------------------------------------------------
    Copyright (c) alexrayne

   All rights reserved.
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:
   - Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
   - Neither the name of ARM nor the names of its contributors may be used
     to endorse or promote products derived from this software without
     specific prior written permission.
   *
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE. *
  ------------------------------------------------------------------------
 * */

#ifndef INTFACES_H
#define INTFACES_H

#include <stdarg.h>
#include "hal_types.h"

#ifdef __unix__
    #include <assert.h>
#else
#include <assert.h>
#endif


#if 1
#define HAL_ASSERT(...) assert(__VA_ARGS__)
#else
#define HAL_ASSERT(...)
#endif



#define ERROR_MAX_LENGTH    25



class HAL_Device{
public:
    bool init_state;
    typedef const_string dev_name;
    typedef const_string error_str;

    HAL_Device(const_string name):init_state(false), _name(name), error(NULL){};
    virtual int init() = 0;
    virtual int deinit() = 0;

    virtual const_string getLastErrorStr(){
      return this->error;
    };

    const_string name() const {return this->_name;};

protected:
    dev_name    _name;
    error_str   error;
};

class Power_Manager{
public:
    enum POWER_STATE{
        WORK,
        SLEEP,
        HALT
    };

    virtual int setPower(POWER_STATE state){return DEV_NOT_IMPLEMENTED;}
    virtual POWER_STATE getPower(){return this->state;}

protected:
    POWER_STATE state;//TODO = HALT;
};




class HAL_IO_Device{
public:
    typedef const_string ioctl_string;
    virtual int IOCtrl(ioctl_string cmd){return DEV_NOT_IMPLEMENTED;}
    virtual DevResult readByte(u8 *data){return DEV_NOT_IMPLEMENTED;}
    virtual DevResult writeByte(u8 data){return DEV_NOT_IMPLEMENTED;}
    virtual int readData(u8 *data, size_t size){return DEV_NOT_IMPLEMENTED;}
    virtual int writeData(const u8 *data, size_t size){return DEV_NOT_IMPLEMENTED;}

private:

};

class HAL_ASYNCIO_Device{
public:
    typedef const_string ioctl_string;
    virtual int IOCtrl(ioctl_string cmd){return DEV_NOT_IMPLEMENTED;}

    // \return - bytes send amount
    virtual int postByte(u8 data){return DEV_NOT_IMPLEMENTED;}
    virtual int postData(const void *data, size_t size){return DEV_NOT_IMPLEMENTED;}

    static const unsigned toInfinite = ~0u;
    virtual PTResult wait_flush(unsigned to = toInfinite){
        return AS_PTRESULT(DEV_NOT_IMPLEMENTED);
    };
    // \return - bytes avail for read
    virtual PTResult wait_avail(size_t size, unsigned to = toInfinite){
        return AS_PTRESULT(DEV_NOT_IMPLEMENTED);
    };
};

class HAL_IOAdress_Device
//        :public HAL_IO_Device
{
    public:
        typedef u32 ioaddr_t;
        ioaddr_t    io_addr() const {return ioaddr;};
        virtual int io_addr(ioaddr_t x) {ioaddr = x; return x;};
    protected:
        ioaddr_t    ioaddr;
};

class HAL_REGs_Device{
public:
    typedef const_string ioctl_string;
    typedef u32 regaddr_t;
    virtual int IOCtrl(ioctl_string cmd){return DEV_NOT_IMPLEMENTED;}
    virtual DevResult readByte(regaddr_t address, u8 *data){return DEV_NOT_IMPLEMENTED;}
    virtual DevResult writeByte(regaddr_t address, u8 data){return DEV_NOT_IMPLEMENTED;}
    virtual int readData(regaddr_t address, void *data, size_t size){return DEV_NOT_IMPLEMENTED;}
    virtual int writeData(regaddr_t address, const void *data, size_t size){return DEV_NOT_IMPLEMENTED;}

private:

};

class HAL_IO_Block_Device{
public:
    typedef const_string ioctl_string;
    typedef uint32_t addr_t;
    virtual int IOCtrl(const_string cmd){return DEV_NOT_IMPLEMENTED;}
    virtual DevResult readByte(addr_t address, u8 *data){return DEV_NOT_IMPLEMENTED;}
    virtual DevResult writeByte(addr_t address, u8 data){return DEV_NOT_IMPLEMENTED;}
    virtual int readData(addr_t address, void *data, size_t size){return DEV_NOT_IMPLEMENTED;}
    virtual int writeData(addr_t address, const void *data, size_t size){return DEV_NOT_IMPLEMENTED;}

private:

};


#include <serial/stdio_hal.hpp>



#endif // INTFACES_H
