# coding: UTF-8

import socket
import time
import tkinter.messagebox

BUFSIZE = 4096

class Lan:

    def __init__(self, timeout, gui=False):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)		#送信の遅延(Nagleアルゴリズム)を無効にする
        self.sock.settimeout(timeout)                                   #タイムアウト
        self.gui = gui

    #ポートオープン
    def open(self, IP, port):
        ret = False

        try:
            self.sock.connect((IP, port))
            ret = True
        except Exception as e:
            if self.gui == True:
                tkinter.messagebox.showerror("Open Error", e)
            else:
                print("Open error")
                print(e)
        
        return ret

    #ポートのクローズ
    def close(self):
        ret = False

        try:
            self.sock.close()
            ret = True
        except Exception as e:
            if self.gui == True:
                tkinter.messagebox.showerror("Close Error", e)
            else:
                print("Close error")
                print(e)
        
        return ret

    #コマンドの送信
    def sendMsg(self, strMsg):
        ret = False

        try:
            strMsg = strMsg + '\r\n'                #ターミネータ「CR+LF」を付加
            self.sock.send(bytes(strMsg, 'utf-8'))  #バイト型に変換し送信
            ret = True
        except Exception as e:
            if self.gui == True:
                tkinter.messagebox.showerror("Send Error", e)
            else:
                print("Send Error")
                print(e)

        return ret
    
    #コマンドの受信
    def receiveMsg(self, timeout):

        msgBuf = bytes(range(0))                    #受信データ

        try:
            start = time.time()                     #タイムアウト用に時間を記録
            while True:
                rcv  = self.sock.recv(BUFSIZE)
                rcv = rcv.strip(b"\r")              #受信データ内の「CR」を削除
                if b"\n" in rcv:                    #ターミネータ「LF」を受信したら終了
                    rcv = rcv.strip(b"\n")          #受信データ内の「LF」を削除
                    msgBuf = msgBuf + rcv
                    msgBuf = msgBuf.decode('utf-8')
                    break
                else:
                    msgBuf = msgBuf + rcv
                
                #タイムアウト処理
                if  time.time() - start > timeout:
                    msgBuf = "Timeout Error"
                    break
        except Exception as e:
            if self.gui == True:
                tkinter.messagebox.showerror("Receive Error", e)
            else:
                print("Receive Error")
                print(e)
            msgBuf = "Error"

        return msgBuf
    
    #コマンドの送受信
    def SendQueryMsg(self, strMsg, timeout):
        ret = Lan.sendMsg(self, strMsg)
        if ret:
            msgBuf_str = Lan.receiveMsg(self, timeout)  #送信が成功したら応答を受信
        else:
            msgBuf_str = "Error"

        return msgBuf_str