package com.bonait.bnframework.HBL.Communication.Siemens;

import android.util.Log;

import com.bonait.bnframework.HBL.Logs.MessageLog;
import com.github.xingshuangs.iot.exceptions.SocketRuntimeException;
import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
import com.github.xingshuangs.iot.protocol.s7.model.DataItem;
import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
import com.github.xingshuangs.iot.protocol.s7.utils.AddressUtil;
import com.github.xingshuangs.iot.utils.FloatUtil;
import com.github.xingshuangs.iot.utils.IntegerUtil;
import com.github.xingshuangs.iot.utils.ShortUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class SiemensHelper extends S7PLC {
    public Boolean IsConnected=false;

    public boolean CancelWrite=false;


    public void Delay(long millis){
        try{
            Thread.sleep(millis);
        }catch(InterruptedException e){

        }
    }

    public boolean ReadBoolean(String address){
        boolean result=false;
        while(true){
            try {
                result=this.readBoolean(address);
                IsConnected=true;
               break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(1000);
            }
        }
        return result;
    }

    public List<Boolean> ReadBoolean(String... address) {
        List<Boolean> result=new ArrayList<>();
        while(true){
            try {
                result=this.readBoolean(Arrays.asList(address));
                IsConnected=true;
                break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(1000);
            }
        }
        return result;
    }

    public short ReadInt16(String address) {
        short result=0;
        while(true){
            try {
                DataItem dataItem = this.readS7Data(AddressUtil.parseByte(address, 2));
                 result= ShortUtil.toInt16(dataItem.getData());
                IsConnected=true;
               break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(1000);
            }
        }
        return result;

    }

    public List<Short> ReadInt16(String... address) {
        List<Short> result=new ArrayList<>();
        while(true){
            try {
                result=this.readInt16(Arrays.asList(address));
                IsConnected=true;
                break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(1000);
            }
        }

        return result;
    }

    public int ReadUInt16(String address) {
        int result=0;
        while(true){
            try {
                DataItem dataItem = this.readS7Data(AddressUtil.parseByte(address, 2));
                result= ShortUtil.toUInt16(dataItem.getData());
                IsConnected=true;
                break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(1000);
            }
        }
        return result;
    }

    public List<Integer> ReadUInt16(String... address) {
        List<Integer> result=new ArrayList<>();
        while(true){
            try {
                result=this.readUInt16(Arrays.asList(address));
                IsConnected=true;
                break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(1000);
            }
        }
        return result;
    }

    public int ReadInt32(String address) {
        int result=0;
        while(true){
            try {
                DataItem dataItem = this.readS7Data(AddressUtil.parseByte(address, 4));
                result= IntegerUtil.toInt32(dataItem.getData());
                IsConnected=true;
                break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(1000);
            }
        }
        return result;
    }

    public List<Integer> ReadInt32(String... address) {
        List<Integer> result=new ArrayList<>();
        while(true){
            try {
                 result=this.readInt32(Arrays.asList(address));
                IsConnected=true;
                break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(1000);
            }
        }
        return result;
    }

    public float ReadFloat32(String address) {
        float result=0f;
        while(true){
            try {
                DataItem dataItem = this.readS7Data(AddressUtil.parseByte(address, 4));
                 result= FloatUtil.toFloat32(dataItem.getData());

                IsConnected=true;
                break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(1000);
            }
        }
        return result;
    }

    public List<Float> ReadFloat32(String... address) {
        List<Float> result=new ArrayList<>();
        while(true){
            try {
                 result=this.readFloat32(Arrays.asList(address));
                IsConnected=true;
                break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(1000);
            }
        }
        return result;
    }

    public void WriteBoolean(String address, boolean data) {
        if(!IsConnected){
            MessageLog.ShowInfo(address+"：写入数据失败，连接已断开");
            return;
        }
        while (true) {
            try {
                this.writeS7Data(AddressUtil.parseBit(address), DataItem.createReqByBoolean(data));
                IsConnected=true;
                break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(100);
                if(CancelWrite)break;
            }
            catch (Exception e){
                MessageLog.ShowError("WriteBoolean 写入异常："+e.toString());
                break;
            }
        }
    }

    public void WriteUInt16(String address, int data) {
        if(!IsConnected){
            MessageLog.ShowInfo(address+"：写入数据失败，连接已断开");
            return;
        }
        while (true) {
            try {
                this.writeByte(address, ShortUtil.toByteArray(data));
                IsConnected=true;
                break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(100);
                if(CancelWrite)break;
            }
            catch (Exception e){
                MessageLog.ShowError("WriteUInt16 写入异常："+e.toString());
                break;
            }
        }
    }

    public void WriteInt16(String address, short data) {
        if(!IsConnected){
            MessageLog.ShowInfo(address+"：写入数据失败，连接已断开");
            return;
        }
        while (true) {
            try {
                Log.e("info","准备写入数据："+data);
                this.writeByte(address, ShortUtil.toByteArray(data));
                IsConnected=true;
                break;
            }
            catch(SocketRuntimeException ex){
                Log.e("socketException","写入："+data+"失败");
                this.close();
                IsConnected=false;
                Delay(100);
                if(CancelWrite)break;
            }
            catch (Exception e){
                MessageLog.ShowError("WriteInt16 写入异常："+e.toString());
                break;
            }
        }
    }

    public void WriteUInt32(String address, long data) {
        if(!IsConnected){
            MessageLog.ShowInfo(address+"：写入数据失败，连接已断开");
            return;
        }
        while (true) {
            try {
                this.writeByte(address, IntegerUtil.toByteArray(data));
                IsConnected=true;
                break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(100);
                if(CancelWrite)break;
            }
            catch (Exception e){
                MessageLog.ShowError("WriteUInt32 写入异常："+e.toString());
                break;
            }
        }
    }

    public void WriteInt32(String address, int data) {
        if(!IsConnected){
            MessageLog.ShowInfo(address+"：写入数据失败，连接已断开");
            return;
        }
        while (true) {
            try {
                this.writeByte(address, IntegerUtil.toByteArray(data));
                IsConnected=true;
                break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(100);
                if(CancelWrite)break;
            }
            catch (Exception e){
                MessageLog.ShowError("WriteInt32 写入异常："+e.toString());
                break;
            }
        }
    }

    public void WriteFloat32(String address, float data) {
        if(!IsConnected){
            MessageLog.ShowInfo(address+"：写入数据失败，连接已断开");
            return;
        }
        while (true) {
            try {
                this.writeByte(address, FloatUtil.toByteArray(data));
                IsConnected=true;
                break;
            }
            catch(SocketRuntimeException ex){
                this.close();
                IsConnected=false;
                Delay(100);
                if(CancelWrite)break;
            }
            catch (Exception e){
                MessageLog.ShowError("WriteFloat32 写入异常："+e.toString());
                break;
            }
        }
    }

    public SiemensHelper(EPlcType PlcType, String ip){
        super(PlcType, ip);
    }

}
