package eu.faircode.netguard;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class GenieActivity extends AppCompatActivity {

    String defaultSendIp = "9.9.9.9"; // 207.x
    String defaultSourceIp = "10.1.10.100";

    boolean foundConnection = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_genie);

    }

    public void getInfo(View view) {
        String someInfo = ServiceSinkhole.getLastInfo();
        ((TextView) findViewById(R.id.genieText)).setText(someInfo);
    }

    public void flipSrcDst(View view) {
        System.out.println("flipping the input source and dest info..");

        TextView spIn = (TextView) findViewById(R.id.sourcePortInput);
        TextView sipIn = (TextView) findViewById(R.id.sourceInput);
        String currSport = spIn.getText().toString();
        String currSrcIp = sipIn.getText().toString();

        TextView dpIn = (TextView) findViewById(R.id.destPortInput);
        TextView dipIn = (TextView) findViewById(R.id.destInput);
        String currDport = dpIn.getText().toString();
        String currDstIp = dipIn.getText().toString();

        sipIn.setText(currDstIp);
        spIn.setText(currDport);
        dipIn.setText(currSrcIp);
        dpIn.setText(currSport);

    }


    public void updateTcpConn(View view) {

        TextView spIn = (TextView) findViewById(R.id.sourcePortInput);
        TextView sipIn = (TextView) findViewById(R.id.sourceInput);

        TextView dpIn = (TextView) findViewById(R.id.destPortInput);
        TextView dipIn = (TextView) findViewById(R.id.destInput);

        String connInfo = ServiceSinkhole.getLastConnInfo();
        String[] cparts = connInfo.split(">");
        int clength = cparts.length;

        if (clength == 4) {
            String newSrcIp = cparts[0];
            String newSport = cparts[1];
            String newDstIp = cparts[2];
            String newDport = cparts[3];

            sipIn.setText(newSrcIp);
            spIn.setText(newSport);
            dipIn.setText(newDstIp);
            dpIn.setText(newDport);

            String itext = "active connection:  " + newSrcIp + ":" + newSport + " to " + newDstIp + ":" + newDport;
            ((TextView) findViewById(R.id.genieText)).setText(itext);

            foundConnection = true;

        } else {
            String itext = "No active connection to: " + dipIn.getText().toString();
            ((TextView) findViewById(R.id.genieText)).setText(itext);
        }

    }

    public void sendTestSyn(View view) {
        String sendInfo = "sendo";
        String sender = getCurrSendStr();

        ServiceSinkhole.setSender(sendInfo, sender);
    }

    public void sendTestRst(View view) {
        String sendInfo = "reset";
        String sender = getCurrSendStr();

        ServiceSinkhole.setSender(sendInfo, sender);
    }

    public void sendTestPsh(View view) {
        String sendInfo = "push";
        String sender = getCurrSendStr();

        ServiceSinkhole.setSender(sendInfo, sender);
    }


    public void sendTestPing(View view) {
        String sendInfo = "ping";
        String sender = getCurrSendStr();

        ServiceSinkhole.setSender(sendInfo, sender);

    }

    public void sendTestUdp(View view) {
        String sendInfo = "udp";
        String sender = getCurrSendStr();

        ServiceSinkhole.setSender(sendInfo, sender);
    }



    private String getCurrSendStr() {

        String srcIp = getSourceIp();
        String srcPort = getSourcePort();
        String sendIp = getSendIp();
        String dstPort = getDestPort();
        String sendTtl = getTtlVal();

        String sendSeq = getSeqNumVal();
        String sendAck = getAckNumVal();

        String sender = srcIp + ">" + sendIp + ">" + srcPort + ">" + dstPort + ">" + sendTtl + ">" + sendSeq + ">" + sendAck;
        System.out.println("GEE Current GUI send info: " + sender);

        return sender;

    }


    private String getSendIp() {
        // get the value of the dest IP in text box
        TextView tv = (TextView) findViewById(R.id.destInput);
        String someDest = tv.getText().toString();
        // TODO verify the inputted IP string is valid
        boolean isValid = checkValidIp(someDest);
        String sendIp = defaultSendIp;
        if (isValid) {
            System.out.println("valid ip input set to: " + someDest);
            sendIp = someDest;
        }

        return sendIp;
    }

    private String getSourceIp() {
        // get the value of the dest IP in text box
        TextView tv = (TextView) findViewById(R.id.sourceInput);
        String someDest = tv.getText().toString();

        boolean isValid = checkValidIp(someDest);
        String sourceIp = defaultSourceIp;
        if (isValid) {
            System.out.println("valid ip input set to: " + someDest);
            sourceIp = someDest;
        }

        return sourceIp;
    }


    private String getSourcePort() {
        // get the value of the dest IP in text box
        TextView tv = (TextView) findViewById(R.id.sourcePortInput);
        String someSrcPort = tv.getText().toString();

        int pnum = getValidPort(someSrcPort);
        return String.valueOf(pnum);
    }

    private String getDestPort() {
        // get the value of the dest IP in text box
        TextView tv = (TextView) findViewById(R.id.destPortInput);
        String someDstPort = tv.getText().toString();
        int pnum = getValidPort(someDstPort);
        return String.valueOf(pnum);
    }

    private String getTtlVal() {
        // get the value of the dest IP in text box
        TextView tv = (TextView) findViewById(R.id.ttlVal);
        String someTtl = tv.getText().toString();
        int ttl = getValidTtl(someTtl);
        return String.valueOf(ttl);
    }


    private String getSeqNumVal() {
        // get the value of the dest IP in text box
        TextView tv = (TextView) findViewById(R.id.tcpSeqInput);
        String someSeq = tv.getText().toString();
        int ttl = getValidSeqAckNum(someSeq);
        return String.valueOf(ttl);
    }

    private String getAckNumVal() {
        // get the value of the dest IP in text box
        TextView tv = (TextView) findViewById(R.id.tcpAckInput);
        String someAck = tv.getText().toString();
        int ttl = getValidSeqAckNum(someAck);
        return String.valueOf(ttl);
    }

    private int getValidSeqAckNum(String inval) {
        boolean is_valid = isNumeric(inval);
        int max_test_val = 90000000;
        int res = 0;
        if (is_valid) {
            int input_num = Integer.parseInt(inval); // TODO change to long for seq ack longs uint16

            if (input_num > 0 && input_num < max_test_val) {
                System.out.println("Enter valid seq / ack val: " + input_num);
                res = input_num;
            } else {
                System.out.println("Invalid seq / ack number input: " + input_num);
                res = 11;
            }
        } else {
            res = 22;
            System.out.println("Not a valid numeric seq / ack input: " + inval);
        }

        return res;
    }

    private int getValidTtl(String inttl) {
        boolean is_valid = isNumeric(inttl);
        int res = 0;
        if (is_valid) {
            int ttlval = Integer.parseInt(inttl);

            if (ttlval > 0 && ttlval < 255) {
                System.out.println("Enter valid ttl val: " + ttlval);
                res = ttlval;
            } else {
                System.out.println("Sike invalid ttl number input: " + ttlval);
                res = 44;
            }
        } else {
            res = 99;
            System.out.println("Sike not a valid numeric ttl input: " + inttl);
        }

        return res;
    }


    private int getValidPort(String inport) {
        boolean is_valid = isNumeric(inport);
        int res = 0;
        if (is_valid) {

            int inp = Integer.parseInt(inport);

            if (inp > 32000 && inp < 62000) {
                res = inp;
            } else {
                res = 30303;
            }

        } else {
            res = 30301;
        }

        return res;

    }

    private boolean checkValidIp(String ip) {

        String[] ip_parts = ip.split("\\.", 4);
        int ilength = ip_parts.length;
        System.out.println("verifying if valid ip input: " + ip + ", length of ip parts after split: " + ilength);

        if (ilength == 4) {
            boolean valid_ip = true;
            for (int j = 0; j < ilength; j++) {
                String n = ip_parts[j];
                boolean is_valid = isNumeric(n);
                System.out.println("checking if valid ip num: " + n + ", is valid num: " + is_valid);
                if (!is_valid) {
                    valid_ip = false;
                }
            }

            if (valid_ip) {
                return true;
            }

        } else {
            return false;
        }

        return true;
    }


    private boolean isNumeric(String nstr) {
        for (char c : nstr.toCharArray()) {
            if (!Character.isDigit(c)) return  false;
        }
        return true;
    }
}