package com.example.httpserver7;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class httprxtx extends Thread {
//    public interface TcpConnectionListener{
//        void onReceive(byte[] data,int len);
//        void onRestart();
//    }
//    TcpConnectionListener listener;
    //private MainActivity mActivity;
    private static boolean flg_loop = false;
    private static boolean flg_accept = false;
    //private String ssidword_str;
    //private String keyword_str;
    //private String doraip_str;
    //private byte reqcmd;
    //private int transperiod;
    private static String serverip;
    private static int serverportnum;
    //private String[] AUTHTYPEItems = {"None","PAP","CHAP","PAP or CHAP"};
    //private String[] PDPTYPEItems = {"IPv4","IPv6","IPv4/IPv6"};
    //private byte retry_cnt = 0;
    //private byte RETRYMAX = 3;
    //private String jpgfname;
    //private String avifname;
    //private File file;
    //private byte flg_rxcont = 0;
    //private int rxlen = 0;
    //private int rxlens = 0;
    //private byte chksum = 0;
    //private DataInputStream in = null;
    //private DataOutputStream out = null;
    //private int len = 0;
    //private byte rxbuf[] = new byte[16000];
    private static byte req_tx = 0;
    private static byte[] txdata;
    private  static int txlen;
    private static ServerSocket echoSocket = null;
    private static Socket clientSocket = null;
    private static byte req_disconnect = 0;
    private Thread clientth;
    private Handler handler = new Handler(Looper.getMainLooper());
    //public httprxtx(MainActivity mainActivity,TcpConnection ){
    //    mActivity = mainActivity;
    //}
    //public void createsocket(String ipaddress, int port) {
    public httprxtx(final String ipaddress, final int port) throws IOException {
//    public httprxtx(TcpConnectionListener listener,final String ipaddress, final int port) throws IOException {
        //Socket clientSocket = null;
//        this.listener = listener;
        InetAddress addr = InetAddress.getByName(ipaddress);
        echoSocket = new ServerSocket(port, 100, addr);
        echoSocket.setSoTimeout(4800000);
        //echoSocket.setSoTimeout(0);
        echoSocket.setReuseAddress(true);
        echoSocket.setReceiveBufferSize(16000);


 //       String str = "接続されました " ;
 //       MainActivity.printString(str);
    }

/*
    public void txstart(){
        if(echoSocket == null){
            return;
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    clientSocket = echoSocket.accept();
                    clientSocket.setSoTimeout(4800000);
                    //clientSocket.setSoTimeout(0);
                    if(clientSocket.isConnected() == true) {
                        in = new DataInputStream(clientSocket.getInputStream());
                        out = new DataOutputStream(clientSocket.getOutputStream());
                    }

                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }).start();
    }
    private void startInputThread(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    while(true){
                        len = in.read(rxbuf);
                        if(clientSocket.isConnected() == false){
                            clientSocket = echoSocket.accept();
                            //req_disconnect = 0;
                            //clientth.stop();
                            //clientSocket.close();


                        }
                        if(req_tx != 0){
                            req_tx = 0;
                            out.write(txdata,0,txlen);
                            out.flush();
                        }
                        if (len > 0) {
                            //listener.onReceive(rxbuf,len);
                            LteSms.RecvData(rxbuf,len);
                        }

                    }
                }catch (IOException e){
                    restart();;
                }
            }
        }).start();
    }
*/

    @Override
    public void run(){
        while (flg_loop) {
            try {
                clientSocket = echoSocket.accept();
                clientSocket.setSoTimeout(4800000);
                //clientSocket.setSoTimeout(0);

                clientth = new EchoThread(clientSocket);
                clientth.start();
                //flg_loop = false;
                //String str = "接続されました " ;
                //MainActivity.printString(str);
            }catch (SocketTimeoutException s){
                //if(clientSocket.isConnected() == true){
                    //req_disconnect = 1;
                    //clientdisconnect();
                    //ClientSocketDisconnect();
                //}

                //clientconnect();
                //restart();
                //clientSocket.close();
                startServer(serverip,serverportnum);
                //echoSocket.close();
            }catch (IOException e) {
                //System.out.println(e);
                //str = e.toString();
                //mActivity.printString(str);
                //restart();
                startServer(serverip,serverportnum);
            }
        }
    }
//    private class AcceptThread extends Thread implements Runnable {
//        //ServerSocket echoSocket = null;
//        //Socket clientSocket = null;
//        String str;
//        private AcceptThread(String ipaddress, int port) throws IOException {
//            //待ち受けポートを指定して新しいサーバソケットを生成しています。
//            echoSocket = new ServerSocket(port);
//            //System.out.println("Serverが起動しました(port=" + echoSocket.getLocalPort() + ")");
//            str = "EchoServerが起動しました(port=" + echoSocket.getLocalPort()  + ")";
//            mActivity.printString(str);
//        }
//        @Override
//        public void run () {
//            try {
//                while (true) {
//                    //acceptメソッドを呼び出し、クライアントからの接続待機状態に入ります。クライアントからの接続要求があると、socketにはクライアントとの通信に利用できるSocketのインスタンスが代入されます。
//                    clientSocket = echoSocket.accept();
//                    //System.out.println("接続されました "+ clientSocket.getRemoteSocketAddress() );
//                    //str = "接続されました " + clientSocket.getRemoteSocketAddress();
//                    //mActivity.printString(str);
//                    //str = clientSocket.getRemoteSocketAddress().toString();
//                    //str = str.substring(1);
//                    //mActivity.printString(str);
//                    new ConnectThread(clientSocket).start();
//                    str = "接続されました " + clientSocket.getInetAddress();
//                    mActivity.printString(str);
//                }
//            } catch (IOException e) {
//                //System.out.println(e);
//                str = "アクセプトエラー：" + e.toString();
//                mActivity.printString(str);
//            }
//        }
//    }
    private class EchoThread extends Thread {
        protected Socket socket;
        protected boolean flg_open;
//        String line;
        String str;
        String str1;
        String str2;
        //BufferedReader is;
        //PrintStream os;
//        int n;
        int s;
//        int seqnum;
//        int e_id;
//        //int len;
//        //int smscmd;
//        int nbytes;
//        byte cmdres = 0;
//        byte srcadr;
//        byte dtnadr;
//        //char rxbuf[] = new char[16000];
//        byte rxbuf2[] = new byte[16000];
//        byte databuf[] = new byte [8000];
//        int i,j,k;
//        String pathname;
//        String state;
//        boolean result;
//        double d1,d2;
//        double lat,lon;
//        //String str1 = "";
//        DateFormat df = new SimpleDateFormat("yyyyMMddHHmmSS");
//        Date date = new Date(System.currentTimeMillis());
//        String strtime = df.format(date);
        public EchoThread(Socket clientSocket) {
            this.socket = clientSocket;
            //this.socket.setSoTimeout(60000);
            this.flg_open = true;
            //flg_loop = true;
            String str = "接続されました "  + this.socket.getInetAddress(); ;
            MainActivity.printString(str);
        }

        //private ConnectThread(Socket sock) {
//             try {
//                 is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//                 os = new PrintStream(socket.getOutputStream());
//             }
//            catch (IOException e) {
//                //System.out.println(e);
//                str = "接続エラー" + e.toString();
//                mActivity.printString4(str);
//            }
//            this.socket = sock;
            //str = "接続されました " + this.socket.getInetAddress();
            //mActivity.printString(str);
            //ssidword_str = mActivity.getssidword();
            //keyword_str = mActivity.getkeyword();
            //doraip_str = mActivity.getdoraip();
            //reqcmd = LteSms.getCMD();
            //transperiod = LteSms.getPERIOD();
//        }

        @Override
        public void run() {
            try {
                //               while (true) {
                //is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                //os = new PrintStream(socket.getOutputStream());

                DataInputStream in = null;
                DataOutputStream out = null;
                if(socket.isConnected() == true) {
                    this.socket = echoSocket.accept();
                    //in = new DataInputStream(socket.getInputStream());
                    out = new DataOutputStream(socket.getOutputStream());
                    in = new DataInputStream(socket.getInputStream());
                }
                //str1 = "受信：";
                //str2 = "送信：";
                // クライアントからのメッセージを待ち、受け取ったメッセージをそのまま返す
//                 while ((line = is.readLine()) != null) {
//                     //System.out.println("受信：" + line);
//                     str += line;
//                     mActivity.printString2(str);
//                 }
                int len = 0;
                byte rxbuf[] = new byte[16000];
                flg_loop = true;
                while(flg_loop) {
                    len = in.read(rxbuf);
                    //len = is.read(rxbuf, 0, 1024);
                    if(req_disconnect != 0){
                        req_disconnect = 0;
                        //clientth.stop();
                        clientSocket.close();
                        str = "ソケットクローズ" ;
                        //mActivity.printString(str);
                        MainActivity.printString(str);
                    }
                     if(this.socket.isConnected() == false){
                         try {
                             this.socket = echoSocket.accept();

                             //clientth = new EchoThread(clientSocket);
                             //clientth.start();
                             flg_accept = true;
                         }catch(IOException e){
                             e.printStackTrace();
                         }
                        this.socket.setSoTimeout(4800000);
                        //req_disconnect = 0;
                        //clientth.stop();
                        //clientSocket.close();
                         if(flg_accept != false) {
                             flg_accept = false;
                             str = "接続" ;
                             //startServer(serverip, serverportnum);
                         }else
                         {
                             str = "接続切れました" ;
                         }
                         //mActivity.printString(str);
                         MainActivity.printString(str);


                    }
//                    else{
//                        this.socket.setSoTimeout(4800000);
//                    }

                    if(req_tx != 0){
                        req_tx = 0;
                        out.write(txdata,0,txlen);
                        out.flush();
                    }
                    if (len > 0) {
                        //listener.onReceive(rxbuf,len);
                        LteSms.RecvData(rxbuf,len);
                    }
                }
                //}
            } catch (IOException e) {
                //System.out.println(e);
                //flg_loop = false;
                str = "接続エラー" + e.toString();
                //mActivity.printString(str);
                MainActivity.printString(str);
                //flg_loop = false;
                startServer(serverip,serverportnum);
            }
        }
    }

  //  public static void init(String ip,int port) {
  //  }
    public static  void startServer(String ip,int port) {
/*
        try{
            Thread.sleep(1000);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
*/
        if (clientSocket != null) {
            if (clientSocket.isConnected() == true) {
                httprxtx.stopServer();
            }
        }
//        if (flg_loop == false){
            try {
                flg_loop = true;
                serverip = ip;
                serverportnum = port;
//    //        init(ip,port);
                Thread mhttp = new httprxtx(ip, port);
                //t.start();
                //httprxtx mhttp = new httprxtx(ip,port);
                mhttp.start();

                //mhttp.txstart();
//            //System.out.println("Server Started !");
//            //super.start();
                MainActivity.printString("Server Started !");
            } catch (IOException e) {
                e.printStackTrace();
                //restart();
            } catch (Exception e) {

            }
//        }
    }
    public static void stopServer(){
        try {
            flg_loop = false;
            echoSocket.close();
            //socket = null;
            MainActivity.printString("Server Stopped !");
        } catch (IOException e) {
            e.printStackTrace();
            //System.out.println(e);
            //str = "クローズエラー" + e.toString();
            //mActivity.printString(str);
        }

    //super.start();
    }
    public void restart(){
        stopServer();
        start();
    }
    public void clientdisconnect(){
        ClientSocketDisconnect();
    }
    public void clientconnect(){

    }
    public static void setReqSend(String sdata,int len){
        txdata = sdata.getBytes();
        txlen = len;
        req_tx = 1;
    }
    public static boolean getsocketconnect(){
        return clientSocket.isConnected();
    }
    public static void ClientSocketDisconnect(){
        req_disconnect = 1;

    }
//    public void run(){
//        try {
//            while (flg_loop) {
//
//            }
//        }catch (Exception e){
//
//        }
//    }


}
