// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';
import 'dart:convert';

import 'package:analysis_server/src/session_logger/session_logger_sink.dart';
import 'package:analysis_server/src/status/diagnostics.dart';
import 'package:analysis_server/src/status/pages.dart';

class SessionLogPage extends DiagnosticPageWithNav implements PostablePage {
  static const _captureFormId = 'capture-entries';

  new(DiagnosticsSite site)
    : super(
        site,
        'session-log',
        'Session communications log',
        description:
            'A log containing all of the communications between the analysis '
            'server and other processes.',
        indentInNav: false,
      );

  @override
  Future<void> generateContent(Map<String, String> params) async {
    var sink = server.sessionLogger.sink;
    if (sink is! SessionLoggerInMemorySink) {
      buf.write('Internal error.');
      return;
    }
    if (sink.isCapturingEntries) {
      buf.write('''
<form action="$path?$_captureFormId=false" method="post">
<input type="submit" class="btn" value="Stop capturing entries" />
</form>
''');
      h1('Current log contents (in progress)');
    } else {
      buf.write('''
<form action="$path?$_captureFormId=true" method="post">
<input type="submit" class="btn" value="Start capturing entries" />
</form>
''');
      h1('Previous log contents');
    }
    // Output the current entries.
    var buffer = StringBuffer();
    var entries = sink.capturedEntries;
    for (var entry in entries) {
      buffer.writeln(json.encode(entry));
    }

    buf.writeln('''
<script>
async function copyToClipboard() {
  var copyText = document.getElementById("sessionLogContent");
  if (copyText) {
    try {
      await navigator.clipboard.writeText(copyText.innerText);
    } catch (err) {
      console.error('Failed to copy: ', err);
    }
  }
}
</script>
<p><button class="btn" onclick="copyToClipboard()">Copy to Clipboard</button></p>
''');

    pre(() {
      buf.write('<code id="sessionLogContent">');
      buf.write(escape('$buffer'));
      buf.writeln('</code>');
    });
  }

  @override
  Future<String> handlePost(Map<String, String> params) async {
    var newCaptureState = params[_captureFormId];
    if (newCaptureState != null) {
      var sink = server.sessionLogger.sink;
      if (sink is SessionLoggerInMemorySink) {
        if (newCaptureState == 'true') {
          sink.startCapture();
        } else {
          sink.stopCapture();
        }
      }
    }
    return path;
  }
}
