// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
In the absence of any formal way to specify interfaces in JavaScript,
here's a skeleton implementation of a playground transport.

        function Transport() {
                // Set up any transport state (eg, make a websocket connection).
                return {
                        Run: function(body, output, options) {
                                // Compile and run the program 'body' with 'options'.
				// Call the 'output' callback to display program output.
                                return {
                                        Kill: function() {
                                                // Kill the running program.
                                        }
                                };
                        }
                };
        }

	// The output callback is called multiple times, and each time it is
	// passed an object of this form.
        var write = {
                Kind: 'string', // 'start', 'stdout', 'stderr', 'end'
                Body: 'string'  // content of write or end status message
        }

	// The first call must be of Kind 'start' with no body.
	// Subsequent calls may be of Kind 'stdout' or 'stderr'
	// and must have a non-null Body string.
	// The final call should be of Kind 'end' with an optional
	// Body string, signifying a failure ("killed", for example).

	// The output callback must be of this form.
	// See PlaygroundOutput (below) for an implementation.
        function outputCallback(write) {
        }
*/

// HTTPTransport is the default transport.
// enableVet enables running vet if a program was compiled and ran successfully.
// If vet returned any errors, display them before the output of a program.
function HTTPTransport(enableVet) {
  'use strict';

  function playback(output, data) {
    // Backwards compatibility: default values do not affect the output.
    var events = data.Events || [];
    var errors = data.Errors || '';
    var status = data.Status || 0;
    var isTest = data.IsTest || false;
    var testsFailed = data.TestsFailed || 0;

    var timeout;
    output({ Kind: 'start' });
    function next() {
      if (!events || events.length === 0) {
        if (isTest) {
          if (testsFailed > 0) {
            output({
              Kind: 'system',
              Body:
                '\n' +
                testsFailed +
                ' test' +
                (testsFailed > 1 ? 's' : '') +
                ' failed.',
            });
          } else {
            output({ Kind: 'system', Body: '\nAll tests passed.' });
          }
        } else {
          if (status > 0) {
            output({ Kind: 'end', Body: 'status ' + status + '.' });
          } else {
            if (errors !== '') {
              // errors are displayed only in the case of timeout.
              output({ Kind: 'end', Body: errors + '.' });
            } else {
              output({ Kind: 'end' });
            }
          }
        }
        return;
      }
      var e = events.shift();
      if (e.Delay === 0) {
        output({ Kind: e.Kind, Body: e.Message });
        next();
        return;
      }
      timeout = setTimeout(function() {
        output({ Kind: e.Kind, Body: e.Message });
        next();
      }, e.Delay / 1000000);
    }
    next();
    return {
      Stop: function() {
        clearTimeout(timeout);
      },
    };
  }

  function error(output, msg) {
    output({ Kind: 'start' });
    output({ Kind: 'stderr', Body: msg });
    output({ Kind: 'end' });
  }

  function buildFailed(output, msg) {
    output({ Kind: 'start' });
    output({ Kind: 'stderr', Body: msg });
    output({ Kind: 'system', Body: '\nGo build failed.' });
  }

  var seq = 0;
  return {
    Run: function(body, output, options) {
      seq++;
      var cur = seq;
      var playing;
      $.ajax('/compile', {
        type: 'POST',
        data: { version: 2, body: body, withVet: enableVet },
        dataType: 'json',
        success: function(data) {
          if (seq != cur) return;
          if (!data) return;
          if (playing != null) playing.Stop();
          if (data.Errors) {
            if (data.Errors === 'process took too long') {
              // Playback the output that was captured before the timeout.
              playing = playback(output, data);
            } else {
              buildFailed(output, data.Errors);
            }
            return;
          }
          if (!data.Events) {
            data.Events = [];
          }
          if (data.VetErrors) {
            // Inject errors from the vet as the first events in the output.
            data.Events.unshift({
              Message: 'Go vet exited.\n\n',
              Kind: 'system',
              Delay: 0,
            });
            data.Events.unshift({
              Message: data.VetErrors,
              Kind: 'stderr',
              Delay: 0,
            });
          }

          if (!enableVet || data.VetOK || data.VetErrors) {
            playing = playback(output, data);
            return;
          }

          // In case the server support doesn't support
          // compile+vet in same request signaled by the
          // 'withVet' parameter above, also try the old way.
          // TODO: remove this when it falls out of use.
          // It is 2019-05-13 now.
          $.ajax('/vet', {
            data: { body: body },
            type: 'POST',
            dataType: 'json',
            success: function(dataVet) {
              if (dataVet.Errors) {
                // inject errors from the vet as the first events in the output
                data.Events.unshift({
                  Message: 'Go vet exited.\n\n',
                  Kind: 'system',
                  Delay: 0,
                });
                data.Events.unshift({
                  Message: dataVet.Errors,
                  Kind: 'stderr',
                  Delay: 0,
                });
              }
              playing = playback(output, data);
            },
            error: function() {
              playing = playback(output, data);
            },
          });
        },
        error: function() {
          error(output, 'Error communicating with remote server.');
        },
      });
      return {
        Kill: function() {
          if (playing != null) playing.Stop();
          output({ Kind: 'end', Body: 'killed' });
        },
      };
    },
  };
}

function SocketTransport() {
  'use strict';

  var id = 0;
  var outputs = {};
  var started = {};
  var websocket;
  if (window.location.protocol == 'http:') {
    websocket = new WebSocket('ws://' + window.location.host + '/socket');
  } else if (window.location.protocol == 'https:') {
    websocket = new WebSocket('wss://' + window.location.host + '/socket');
  }

  websocket.onclose = function() {
    console.log('websocket connection closed');
  };

  websocket.onmessage = function(e) {
    var m = JSON.parse(e.data);
    var output = outputs[m.Id];
    if (output === null) return;
    if (!started[m.Id]) {
      output({ Kind: 'start' });
      started[m.Id] = true;
    }
    output({ Kind: m.Kind, Body: m.Body });
  };

  function send(m) {
    websocket.send(JSON.stringify(m));
  }

  return {
    Run: function(body, output, options) {
      var thisID = id + '';
      id++;
      outputs[thisID] = output;
      send({ Id: thisID, Kind: 'run', Body: body, Options: options });
      return {
        Kill: function() {
          send({ Id: thisID, Kind: 'kill' });
        },
      };
    },
  };
}

function PlaygroundOutput(el) {
  'use strict';

  return function(write) {
    if (write.Kind == 'start') {
      el.innerHTML = '';
      return;
    }

    var cl = 'system';
    if (write.Kind == 'stdout' || write.Kind == 'stderr') cl = write.Kind;

    var m = write.Body;
    if (write.Kind == 'end') {
      m = '\nProgram exited' + (m ? ': ' + m : '.');
    }

    if (m.indexOf('IMAGE:') === 0) {
      // TODO(adg): buffer all writes before creating image
      var url = 'data:image/png;base64,' + m.substr(6);
      var img = document.createElement('img');
      img.src = url;
      el.appendChild(img);
      return;
    }

    // ^L clears the screen.
    var s = m.split('\x0c');
    if (s.length > 1) {
      el.innerHTML = '';
      m = s.pop();
    }

    m = m.replace(/&/g, '&amp;');
    m = m.replace(/</g, '&lt;');
    m = m.replace(/>/g, '&gt;');

    var needScroll = el.scrollTop + el.offsetHeight == el.scrollHeight;

    var span = document.createElement('span');
    span.className = cl;
    span.innerHTML = m;
    el.appendChild(span);

    if (needScroll) el.scrollTop = el.scrollHeight - el.offsetHeight;
  };
}

(function() {
  function lineHighlight(error) {
    var regex = /prog.go:([0-9]+)/g;
    var r = regex.exec(error);
    while (r) {
      $('.lines div')
        .eq(r[1] - 1)
        .addClass('lineerror');
      r = regex.exec(error);
    }
  }
  function highlightOutput(wrappedOutput) {
    return function(write) {
      if (write.Body) lineHighlight(write.Body);
      wrappedOutput(write);
    };
  }
  function lineClear() {
    $('.lineerror').removeClass('lineerror');
  }

  // opts is an object with these keys
  //  codeEl - code editor element
  //  outputEl - program output element
  //  runEl - run button element
  //  fmtEl - fmt button element (optional)
  //  fmtImportEl - fmt "imports" checkbox element (optional)
  //  shareEl - share button element (optional)
  //  shareURLEl - share URL text input element (optional)
  //  shareRedirect - base URL to redirect to on share (optional)
  //  toysEl - toys select element (optional)
  //  enableHistory - enable using HTML5 history API (optional)
  //  transport - playground transport to use (default is HTTPTransport)
  //  enableShortcuts - whether to enable shortcuts (Ctrl+S/Cmd+S to save) (default is false)
  //  enableVet - enable running vet and displaying its errors
  function playground(opts) {
    var code = $(opts.codeEl);
    var transport = opts['transport'] || new HTTPTransport(opts['enableVet']);
    var running;

    // autoindent helpers.
    function insertTabs(n) {
      // find the selection start and end
      var start = code[0].selectionStart;
      var end = code[0].selectionEnd;
      // split the textarea content into two, and insert n tabs
      var v = code[0].value;
      var u = v.substr(0, start);
      for (var i = 0; i < n; i++) {
        u += '\t';
      }
      u += v.substr(end);
      // set revised content
      code[0].value = u;
      // reset caret position after inserted tabs
      code[0].selectionStart = start + n;
      code[0].selectionEnd = start + n;
    }
    function autoindent(el) {
      var curpos = el.selectionStart;
      var tabs = 0;
      while (curpos > 0) {
        curpos--;
        if (el.value[curpos] == '\t') {
          tabs++;
        } else if (tabs > 0 || el.value[curpos] == '\n') {
          break;
        }
      }
      setTimeout(function() {
        insertTabs(tabs);
      }, 1);
    }

    // NOTE(cbro): e is a jQuery event, not a DOM event.
    function handleSaveShortcut(e) {
      if (e.isDefaultPrevented()) return false;
      if (!e.metaKey && !e.ctrlKey) return false;
      if (e.key != 'S' && e.key != 's') return false;

      e.preventDefault();

      // Share and save
      share(function(url) {
        window.location.href = url + '.go?download=true';
      });

      return true;
    }

    function keyHandler(e) {
      if (opts.enableShortcuts && handleSaveShortcut(e)) return;

      if (e.keyCode == 9 && !e.ctrlKey) {
        // tab (but not ctrl-tab)
        insertTabs(1);
        e.preventDefault();
        return false;
      }
      if (e.keyCode == 13) {
        // enter
        if (e.shiftKey) {
          // +shift
          run();
          e.preventDefault();
          return false;
        }
        if (e.ctrlKey) {
          // +control
          fmt();
          e.preventDefault();
        } else {
          autoindent(e.target);
        }
      }
      return true;
    }
    code.unbind('keydown').bind('keydown', keyHandler);
    var outdiv = $(opts.outputEl).empty();
    var output = $('<pre/>').appendTo(outdiv);

    function body() {
      return $(opts.codeEl).val();
    }
    function setBody(text) {
      $(opts.codeEl).val(text);
    }
    function origin(href) {
      return ('' + href)
        .split('/')
        .slice(0, 3)
        .join('/');
    }

    var pushedEmpty = window.location.pathname == '/';
    function inputChanged() {
      if (pushedEmpty) {
        return;
      }
      pushedEmpty = true;
      $(opts.shareURLEl).hide();
      window.history.pushState(null, '', '/');
    }
    function popState(e) {
      if (e === null) {
        return;
      }
      if (e && e.state && e.state.code) {
        setBody(e.state.code);
      }
    }
    var rewriteHistory = false;
    if (
      window.history &&
      window.history.pushState &&
      window.addEventListener &&
      opts.enableHistory
    ) {
      rewriteHistory = true;
      code[0].addEventListener('input', inputChanged);
      window.addEventListener('popstate', popState);
    }

    function setError(error) {
      if (running) running.Kill();
      lineClear();
      lineHighlight(error);
      output
        .empty()
        .addClass('error')
        .text(error);
    }
    function loading() {
      lineClear();
      if (running) running.Kill();
      output.removeClass('error').text('Waiting for remote server...');
    }
    function run() {
      loading();
      running = transport.Run(
        body(),
        highlightOutput(PlaygroundOutput(output[0]))
      );
    }

    function fmt() {
      loading();
      var data = { body: body() };
      if ($(opts.fmtImportEl).is(':checked')) {
        data['imports'] = 'true';
      }
      $.ajax('/fmt', {
        data: data,
        type: 'POST',
        dataType: 'json',
        success: function(data) {
          if (data.Error) {
            setError(data.Error);
          } else {
            setBody(data.Body);
            setError('');
          }
        },
      });
    }

    var shareURL; // jQuery element to show the shared URL.
    var sharing = false; // true if there is a pending request.
    var shareCallbacks = [];
    function share(opt_callback) {
      if (opt_callback) shareCallbacks.push(opt_callback);

      if (sharing) return;
      sharing = true;

      var sharingData = body();
      $.ajax('/share', {
        processData: false,
        data: sharingData,
        type: 'POST',
        contentType: 'text/plain; charset=utf-8',
        complete: function(xhr) {
          sharing = false;
          if (xhr.status != 200) {
            alert('Server error; try again.');
            return;
          }
          if (opts.shareRedirect) {
            window.location = opts.shareRedirect + xhr.responseText;
          }
          var path = '/p/' + xhr.responseText;
          var url = origin(window.location) + path;

          for (var i = 0; i < shareCallbacks.length; i++) {
            shareCallbacks[i](url);
          }
          shareCallbacks = [];

          if (shareURL) {
            shareURL
              .show()
              .val(url)
              .focus()
              .select();

            if (rewriteHistory) {
              var historyData = { code: sharingData };
              window.history.pushState(historyData, '', path);
              pushedEmpty = false;
            }
          }
        },
      });
    }

    $(opts.runEl).click(run);
    $(opts.fmtEl).click(fmt);

    if (
      opts.shareEl !== null &&
      (opts.shareURLEl !== null || opts.shareRedirect !== null)
    ) {
      if (opts.shareURLEl) {
        shareURL = $(opts.shareURLEl).hide();
      }
      $(opts.shareEl).click(function() {
        share();
      });
    }

    if (opts.toysEl !== null) {
      $(opts.toysEl).bind('change', function() {
        var toy = $(this).val();
        $.ajax('/doc/play/' + toy, {
          processData: false,
          type: 'GET',
          complete: function(xhr) {
            if (xhr.status != 200) {
              alert('Server error; try again.');
              return;
            }
            setBody(xhr.responseText);
          },
        });
      });
    }
  }

  window.playground = playground;
})();
