<div class="standardContainer">
    <div class="ui basic segment">
        <h2>TCP Proxy</h2>
        <p>Proxy traffic flow on layer 3 via TCP/IP</p>
    </div>
    <button class="ui basic orange button" id="addProxyConfigButton"><i class="ui add icon"></i> Add Proxy Config</button>
    <button class="ui basic circular right floated icon button" onclick="initProxyConfigList();" title="Refresh List"><i class="ui green refresh icon"></i></button>
    <div class="ui divider"></div>
    <div class="ui basic segment" id="addproxyConfig"  style="display:none;">
        <h3>TCP Proxy Config</h3>
        <p>Create or edit a new proxy instance</p>
        <form id="tcpProxyForm" class="ui form">
            <div class="field" style="display:none;">
                <label>UUID</label>
                <input type="text" name="uuid">
            </div>
            <div class="field">
                <label>Name</label>
                <input type="text" name="name" placeholder="Config Name">
            </div>
            <div class="field">
                <label>Port A</label>
                <input type="text" name="porta" placeholder="First address or port">
            </div>
                <div class="field">
                <label>Port B</label>
            <input type="text" name="portb" placeholder="Second address or port">
            </div>
            <div class="field">
                <label>Timeout (s)</label>
                <input type="text" name="timeout" placeholder="Timeout (s)">
            </div>
            <div class="field">
                <label>Mode</label>
                <select name="mode" class="ui dropdown">
                    <option value="">Select Mode</option>
                    <option value="listen">Listen</option>
                    <option value="transport">Transport</option>
                    <option value="starter">Starter</option>
                </select>
            </div>
            <button id="addTcpProxyButton" class="ui basic button" type="submit"><i class="ui blue add icon"></i> Create</button>  
            <button id="editTcpProxyButton" class="ui basic button" onclick="confirmEditTCPProxyConfig(event);"><i class="ui blue save icon"></i> Update</button>  
            <button class="ui basic red button" onclick="event.preventDefault(); cancelTCPProxyEdit(event);"><i class="ui red remove icon"></i> Cancel</button>  
            <div class="ui basic inverted segment" style="background-color: #414141; border-radius: 0.6em;">
                <h3>Proxy Mode Instructions</h3>
                <p>TCP Proxy support the following TCP sockets proxy modes</p>
                <table class="ui celled padded inverted basic table">
                    <thead>
                      <tr><th class="single line">Mode</th>
                      <th>Public-IP</th>
                      <th>Concurrent Access</th>
                      <th>Flow Diagram</th>
                    </tr></thead>
                    <tbody>
                      <tr>
                        <td>
                          <h4 class="ui center aligned inverted header">Transport</h4>
                        </td>
                        <td class="single line">
                            Server: <i class="ui green check icon"></i><br>
                            A: <i class="ui remove icon"></i><br>
                            B: <i class="ui green check icon"></i> (or same LAN)<br>
                        </td>
                        <td>
                            <i class="ui green check icon"></i>
                        </td>
                        <td>Port A (e.g. 25565) <i class="arrow right icon"></i> Server<br>
                            Server <i class="arrow right icon"></i> Port B (e.g. 192.168.0.2:25565)<br>
                            <small>Traffic from Port A will be forward to Port B's (IP if provided and) Port</small>
                        </td>
                      </tr>
                      <tr>
                        <td>
                          <h4 class="ui center aligned inverted header">Listen</h4>
                        </td>
                        <td class="single line">
                            Server: <i class="ui green check icon"></i><br>
                            A: <i class="ui remove icon"></i><br>
                            B: <i class="ui remove icon"></i><br>
                        </td>
                        <td>
                            <i class="ui red times icon"></i>
                        </td>
                        <td>Port A (e.g. 8080) <i class="arrow right icon"></i> Server<br>
                            Port B (e.g. 8081) <i class="arrow right icon"></i> Server<br>
                            <small>Server will act as a bridge to proxy traffic between Port A and B</small>
                        </td>
                      </tr>
                      <tr>
                        <td>
                          <h4 class="ui center aligned inverted header">Starter</h4>
                        </td>
                        <td class="single line">
                            Server: <i class="ui times icon"></i><br>
                            A: <i class="ui green check icon"></i><br>
                            B: <i class="ui green check icon"></i><br>
                        </td>
                        <td>
                            <i class="ui red times icon"></i>
                        </td>
                        <td>Server <i class="arrow right icon"></i> Port A (e.g. remote.local.:8080) <br>
                            Server <i class="arrow right icon"></i> Port B (e.g. recv.local.:8081) <br>
                            <small>Port A and B will be actively bridged</small>
                        </td>
                      </tr>
                    </tbody>
                  </table>
                </div>
        </form>
        <div class="ui divider"></div>
    </div>
    <div class="ui basic segment" style="margin-top: 0;">
        <h3>TCP Proxy Configs</h3>
        <p>A list of TCP proxy configs created on this host. To enable them, use the toggle button on the right.</p>
        <div style="overflow-x: auto; min-height: 400px;">
            <table id="proxyTable" class="ui celled unstackable table">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Port/Addr A</th>
                        <th>Port/Addr B</th>
                        <th>Mode</th>
                        <th>Timeout (s)</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>

                </tbody>
            </table>
        </div>
    </div>
</div>
    <script>
        let editingTCPProxyConfigUUID = ""; //The current editing TCP Proxy config UUID

        $("#tcpProxyForm .dropdown").dropdown();
        $('#tcpProxyForm').on('submit', function(event) {
            event.preventDefault();
            var form = $(this);

            var formValid = validateTCPProxyConfig(form);
            if (!formValid){
                return;
            }

            // Send the AJAX POST request
            $.ajax({
                type: 'POST',
                url: '/api/tcpprox/config/add',
                data: form.serialize(),
                success: function(response) {
                    if (response.error) {
                        msgbox(response.error, false, 6000);
                    }else{
                        msgbox("Config Added");
                    }
                    clearTCPProxyAddEditForm();
                    initProxyConfigList();
                    $("#addproxyConfig").slideUp("fast");
                },
                error: function() {
                    msgbox('An error occurred while processing the request', false);
                }
            });
        });

        //Add proxy button pressed. Show add TCP proxy menu
        $("#addProxyConfigButton").on("click", function(){
            $('#addproxyConfig').slideToggle('fast');
            $("#addTcpProxyButton").show();
            $("#editTcpProxyButton").hide();
        });

            
        function clearTCPProxyAddEditForm(){
            $('#tcpProxyForm input, #tcpProxyForm select').val('');
            $('#tcpProxyForm select').dropdown('clear');
        }

        function cancelTCPProxyEdit(event) {
            clearTCPProxyAddEditForm();
            $('#addproxyConfig').slideUp('fast');
        }

        function validateTCPProxyConfig(form){
            //Check if name is filled. If not, generate a random name for it
            var name = form.find('input[name="name"]').val()
            if (name == ""){
                let randomName = "Proxy Rule (#" + Math.round(Date.now()/1000) + ")";
                form.find('input[name="name"]').val(randomName);
            }

            // Validate timeout is an integer
            var timeout = parseInt(form.find('input[name="timeout"]').val());
            if (form.find('input[name="timeout"]').val() == ""){
                //Not set. Assign a random one to it
                form.find('input[name="timeout"]').val("10");
                timeout = 10;
            }
            
            if (isNaN(timeout)) {
                form.find('input[name="timeout"]').parent().addClass("error");
                msgbox('Timeout must be a valid integer', false, 5000);
                return false;
            }else{
                form.find('input[name="timeout"]').parent().removeClass("error");
            }

            // Validate mode is selected
            var mode = form.find('select[name="mode"]').val();
            if (mode === '') {
                form.find('select[name="mode"]').parent().addClass("error");
                msgbox('Please select a mode', false, 5000);
                return false;
            }else{
                form.find('select[name="mode"]').parent().removeClass("error");
            }
            return true;
        }

        function renderProxyConfigs(proxyConfigs) {
            var tableBody = $('#proxyTable tbody');
            tableBody.empty();
            if (proxyConfigs.length === 0) {
            var noResultsRow = $('<tr><td colspan="7"><i class="green check circle icon"></i>No Proxy Configs</td></tr>');
                tableBody.append(noResultsRow);
            } else {
               
                proxyConfigs.forEach(function(config) {
                    var runningLogo = 'Stopped';
                    var runningClass = "stopped";
                    var startButton = `<button onclick="startTcpProx('${config.UUID}');" class="ui button" title="Start Proxy"><i class="play icon"></i> Start Proxy</button>`;
                    if (config.Running){
                        runningLogo = 'Running';
                        startButton = `<button onclick="stopTcpProx('${config.UUID}');" class="ui button" title="Start Proxy"><i class="red stop icon"></i> Stop Proxy</button>`;
                        runningClass = "running"
                    }

                    var modeText = "Unknown";
                    if (config.Mode == 0){
                        modeText = "Listen";
                    }else if (config.Mode == 1){
                        modeText = "Transport";
                    }else if (config.Mode == 2){
                        modeText = "Starter";
                    }

                    var thisConfig = encodeURIComponent(JSON.stringify(config));

                    var row = $(`<tr class="tcproxConfig ${runningClass}" uuid="${config.UUID}" config="${thisConfig}">`);
                    row.append($('<td>').html(`
                        ${config.Name}
                        <div class="statusText">${runningLogo}</div>`));
                    row.append($('<td>').text(config.PortA));
                    row.append($('<td>').text(config.PortB));
                    row.append($('<td>').text(modeText));
                    row.append($('<td>').text(config.Timeout));
                    row.append($('<td>').html(`
                        <div class="ui basic vertical fluid tiny buttons">
                            <button class="ui button" onclick="validateProxyConfig('${config.UUID}', this);" title="Validate Config"><i class="teal question circle outline icon"></i> CXN Test</button>
                            ${startButton}
                            <button onclick="editTCPProxyConfig('${config.UUID}');" class="ui button" title="Edit Config"><i class="edit icon"></i> Edit </button>
                            <button onclick="deleteTCPProxyConfig('${config.UUID}');" class="ui red basic button" title="Delete Config"><i class="trash icon"></i> Remove</button>
                        </div>
                    `));
                    tableBody.append(row);
                });
            }
        }

        function getConfigDetailsFromDOM(configUUID){
            let thisConfig = null;
            $(".tcproxConfig").each(function(){
                let uuid = $(this).attr("uuid");
                if (configUUID == uuid){
                    //This is the one we are looking for
                    thisConfig = JSON.parse(decodeURIComponent($(this).attr("config")));
                }
            });
            return thisConfig;
        }   

        function validateProxyConfig(configUUID, btn){
            $(btn).html(`<i class="ui loading spinner icon"></i>`);
            $.ajax({
                url: "/api/tcpprox/config/validate",
                data: {uuid: configUUID},
                success: function(data){
                    if (data.error != undefined){
                        let errormsg = data.error.charAt(0).toUpperCase() + data.error.slice(1);
                        $(btn).html(`<i class="red times icon"></i> ${errormsg}`);
                        msgbox(data.error, false, 6000);
                    }else{
                        $(btn).html(`<i class="green check icon"></i> Config Valid`);
                        msgbox("Config Check Passed");
                    }
                }
            })   
        }

        function editTCPProxyConfig(configUUID){
            let targetConfig = getConfigDetailsFromDOM(configUUID);
            if (targetConfig != null){
                $("#addTcpProxyButton").hide();
                $("#editTcpProxyButton").show();
               $.each(targetConfig, function(key, value) {
                    var field = $("#tcpProxyForm").find('[name="' + key.toLowerCase() + '"]');
                    if (field.length > 0) {
                        if (field.is('input')) {
                            field.val(value);
                        }else if (field.is('select')){
                            if (key.toLowerCase() == "mode"){
                                if (value == 0){
                                    value = "listen";
                                }else if (value == 1){
                                    value = "transport";
                                }else if (value == 2){
                                    value = "starter";
                                }
                            }
                            $(field).dropdown("set selected", value);
                        }
                    }
                });
                editingTCPProxyConfigUUID = configUUID;
                $("#addproxyConfig").slideDown("fast");

            }else{
                msgbox("Unable to load target config", false);
            }
        }

        function confirmEditTCPProxyConfig(event){
            event.preventDefault();
            event.stopImmediatePropagation();
            var form = $("#tcpProxyForm");

            var formValid = validateTCPProxyConfig(form);
            if (!formValid){
                return;
            }

            // Send the AJAX POST request
            $.ajax({
                type: 'POST',
                url: '/api/tcpprox/config/edit',
                data: form.serialize(),
                success: function(response) {
                    if (response.error) {
                        msgbox(response.error, false, 6000);
                    }else{
                        msgbox("Config Updated");
                    }
                    initProxyConfigList();
                    clearTCPProxyAddEditForm();
                    $("#addproxyConfig").slideUp("fast");
                },
                error: function() {
                    msgbox('An error occurred while processing the request', false);
                }
            });
        }

        function deleteTCPProxyConfig(configUUID){
            $.ajax({
                url: "/api/tcpprox/config/delete",
                method: "POST",
                data: {uuid: configUUID},
                success: function(data){
                    if (data.error != undefined){
                        msgbox(data.error, false, 6000);
                    }else{
                        msgbox("Proxy Config Removed");
                        initProxyConfigList();
                    }
                }
            })
        }

        //Start a TCP proxy by their config UUID
        function startTcpProx(configUUID){
            $.ajax({
                url: "/api/tcpprox/config/start",
                method: "POST",
                data: {uuid: configUUID},
                success: function(data){
                    if (data.error != undefined){
                        msgbox(data.error, false, 6000);
                    }else{
                        msgbox("Service Started");
                        initProxyConfigList();
                    }
                }

            });
        }

        //Stop a TCP proxy by their config UUID
        function stopTcpProx(configUUID){
            $.ajax({
                url: "/api/tcpprox/config/stop",
                method: "POST",
                data: {uuid: configUUID},
                success: function(data){
                    if (data.error != undefined){
                        msgbox(data.error, false, 6000);
                    }else{
                        msgbox("Service Stopped");
                        initProxyConfigList();
                    }
                }

            });
        }

        function initProxyConfigList(){
            $.ajax({
                type: 'GET',
                url: '/api/tcpprox/config/list',
                success: function(response) {
                    renderProxyConfigs(response);
                },
                error: function() {
                    msgbox('Unable to load proxy configs', false);
                }
            });
        }
        initProxyConfigList();
    </script>
</div>