# -*- coding: UTF-8 -*-
# ==============================================================================

# ------------------------------------------------------------------------------
# Project: pysiril ( Python SiriL )
#
# This is a library to interface python to Siril.
# ------------------------------------------------------------------------------
#    Author:  M27trognondepomme <pebe92 (at) gmail.com>
#
# This program is provided without any guarantee.
#
# The license is  LGPL-v3
# For details, see GNU General Public License, version 3 or later.
#                        "https://www.gnu.org/licenses/gpl.html"
# ------------------------------------------------------------------------------
import sys
import os

# ==============================================================================
if sys.platform.startswith('win32'):
    try:
        import win32pipe
        import win32file
    except:
        pass
else:
    from fcntl import fcntl, F_GETFL, F_SETFL
    from os import O_NONBLOCK, read

# ==============================================================================
class cpipe:
    def __init__(self,mode, trace):
        self.hnd = None
        self.mode = mode
        self.tr   = trace
        self.name = None

    def open(self, name ):
        self.name = name
        if self.hnd != None :
            return False
        if sys.platform.startswith('win32'):
            try:
                if self.mode == 'w' :
                    mode_acces_pipe=win32file.GENERIC_WRITE
                else:
                    mode_acces_pipe=win32file.GENERIC_READ

                self.hnd = win32file.CreateFile( name, mode_acces_pipe , 0, None, win32file.OPEN_EXISTING, 0, None )

                if self.mode == 'w' :
                    option = win32pipe.PIPE_READMODE_MESSAGE | win32pipe.PIPE_NOWAIT
                    res = win32pipe.SetNamedPipeHandleState(self.hnd, option, None, None)
                    if res == 0:
                        self.tr.log("%s: SetNamedPipeHandleState return code: %d " % (name, res ))
            except Exception as e:
                self.tr.error("broken pipe (" + self.mode + "), bye bye")
                self.tr.error("*** cpipe::open() " + str(e) )
                self.running = False
                return False
        else:
            try:
                if self.mode == 'w' :
                    self.hnd = os.open(name, os.O_WRONLY)
                if self.mode == 'r' :
                    self.hnd = open(name, "r" )
                    flags = fcntl(self.hnd, F_GETFL)
                    fcntl(self.hnd, F_SETFL, flags | O_NONBLOCK)
            except Exception as e :
                self.tr.error("*** cpipe::open() " + str(e) )
                return False
        return True

    def close(self):
        if self.hnd == None :
            return
        if sys.platform.startswith('win32'):
            win32file.CloseHandle(self.hnd)
        else:
            if self.mode == 'w' :
                os.close(self.hnd)
            else:
                self.hnd.close()

    def write(self, line ):
        if self.hnd == None :
            return False
        if self.mode != 'w' :
            return False
        try:
            if sys.platform.startswith('win32'):
                win32file.WriteFile(self.hnd, line.encode())
            else:
                os.write( self.hnd,line.encode() )
        except Exception as e:
            self.tr.error("*** cpipe::write() " + str(e) )
            return False
        return True

    def read(self ):
        try:
            if self.hnd == None :
                return ''
            if self.mode != 'r' :
                return ''
            if sys.platform.startswith('win32'):
                try:
                    ret_value = win32file.ReadFile(self.hnd, 1024)
                    line = ret_value[1].decode("utf-8")
                except:
                    if not os.path.exists( self.name ) :
                        return None
                    line=''
            else:
                try:
                    line = self.hnd.readline()
                except:
                    if not os.path.exists( self.name ) :
                        return None
                    line=''
        except (KeyboardInterrupt, SystemExit):
            sys.exit()
            return None
        except Exception as e :
            self.tr.error("*** cpipe::read() " + str(e) )

        return line

