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

// @dart = 2.8

import 'dart:core';

import '../render/ast.dart';
import '../types.dart';
import 'index.dart';

enum SourceLang { cpp, rust, go, unknown }

extension on SourceLang {
  String toUnqualifiedName() =>
      toString().substring(runtimeType.toString().length + 1);
}

class SourceLangContextMixin {
  // ignore: use_setters_to_change_properties
  void initSourceLangContextMixin(Report report) {
    _report = report;
  }

  Report _report;

  SourceLang get lang => _lang(this);

  final _lang = Lazy<SourceLang, ProgramContext>(
      (ProgramContext self) => _fuzzyDetectLang(self._report));
}

class SourceLangCompileContextMixin {
  bool get isRust => _isRust(this);

  final _isRust = Lazy<bool, CompileUnitContext>((CompileUnitContext self) =>
      self.name.endsWith('.rs') || self.name.startsWith('[crate: '));

  bool get isCFamilyFileExtension => _isCFamilyFileExtension(this);

  static final _cFamilyFileExtensionRegex = RegExp(r'\.(c|cc|cpp|h|hh|hpp)$');

  final _isCFamilyFileExtension = Lazy<bool, CompileUnitContext>(
      (CompileUnitContext self) =>
          _cFamilyFileExtensionRegex.hasMatch(self.name));
}

class SourceLangQuery extends Query
    implements QueryReport, IgnorePageInHeatmapFilter {
  static const String description =
      'Groups binaries based on the programming language they are '
      'predominantly written in.';

  @override
  String getDescription() => description;

  @override
  void addReport(Report report) {
    _tallies[report.context.lang]
      ..size += report.fileTotal
      ..count += 1;
  }

  @override
  void mergeWith(Iterable<Query> others) {
    for (final other in others) {
      if (other is SourceLangQuery) {
        for (final entry in other._tallies.entries) {
          _tallies[entry.key] += entry.value;
        }
      } else {
        throw Exception('$other must be $runtimeType');
      }
    }
  }

  @override
  QueryReport distill() => this;

  final _tallies = Map<SourceLang, Tally>.fromEntries(
      SourceLang.values.map((s) => MapEntry(s, Tally.zero())));

  @override
  String toString() => printMapSorted(_tallies);

  @override
  Iterable<AnyNode> export() {
    final sortedBySize = _tallies.keys.toList()
      ..sort((a, b) => -_tallies[a].size.compareTo(_tallies[b].size));
    return sortedBySize.map((k) => Node(
            title: StyledString([
          AddColor.white(Plain(k.toUnqualifiedName())),
          Plain(': ${_tallies[k]}'),
        ])));
  }
}

SourceLang _fuzzyDetectLang(Report report) {
  const goKeyLibraries = <String>{
    'net/http',
    'crypto/tls',
    'github.com/golang/protobuf/proto',
    'netstack',
    'gvisor.dev/gvisor/pkg/tcpip/transport/tcp',
    'math/big',
    'gvisor.dev/gvisor/pkg/tcpip/stack',
    'reflect',
    'vendor/golang.org/x/text/unicode/norm',
    'fuchsia.googlesource.com/pmd/pkgfs',
    'encoding/json',
    'gvisor.dev/gvisor/pkg/state',
    'syscall/zx/fidl',
    'regexp/syntax',
    'vendor/golang.org/x/net/dns/dnsmessage',
    'crypto/x509',
    'netstack/filter',
    'syscall/zx/io',
    'golang.org/x/net/dns/dnsmessage',
    'crypto/ed25519/internal/edwards25519',
    'strconv',
    'regexp',
    'vendor/golang.org/x/net/idna',
    'encoding/asn1',
    'fidl/fuchsia/posix/socket',
    'fidl/fuchsia/io',
    'crypto/elliptic',
    'compress/flate',
    'fmt',
    'runtime/pprof',
    'syscall/zx/fdio',
    'encoding/hex',
    'crypto/rand',
    'gvisor.dev/gvisor/pkg/tcpip/link/loopback',
    'fuchsia.googlesource.com/pmd/blobfs',
    'gvisor.dev/gvisor/pkg/tcpip/network/hash',
    'fidl/fuchsia/storage/metrics',
    'crypto/dsa',
    'crypto/rc4',
    'container/heap',
    'gvisor.dev/gvisor/pkg/tcpip/seqnum',
    'fuchsia.googlesource.com/pmd/allowlist',
    'amber/urlscope',
    'hash/fnv',
    'netstack/link',
    'internal/testlog',
    'runtime/internal/sys',
    'vendor/golang.org/x/text/transform',
    'fidl/fuchsia/mem',
    'syscall/zx/mem',
    'internal/oserror',
    'sync/atomic',
    'unicode/utf16',
    'crypto/internal/randutil',
    'netstack/util',
    'fuchsia.googlesource.com/pmd/iou',
    'math/bits',
    'runtime/cgo',
    'crypto/subtle',
    'net/http/httptrace',
    'vendor/golang.org/x/crypto/cryptobyte/asn1',
    'runtime/internal/atomic',
    'gvisor.dev/gvisor/pkg/rand',
    'gvisor.dev/gvisor/pkg/tcpip/hash/jenkins',
    'gvisor.dev/gvisor/pkg/linewriter',
  };
  var numCppUnits = 0;
  var numRustUnits = 0;
  var numGoUnits = 0;
  for (var compileUnit in report.compileUnits) {
    if (compileUnit.context.isCFamilyFileExtension) {
      numCppUnits += 1;
    } else if (compileUnit.context.isRust) {
      numRustUnits += 1;
    } else if (goKeyLibraries.contains(compileUnit.name)) {
      numGoUnits += 1;
    }
  }
  // Preferentially select rust in case multiple languages mix.
  if (numRustUnits > 0 &&
      numRustUnits >= numGoUnits &&
      // Account for Rust binaries linking in the C++ libunwind library.
      numCppUnits < numRustUnits * 2) {
    return SourceLang.rust;
  }
  if (numGoUnits >= numCppUnits &&
      numGoUnits >= numRustUnits &&
      numGoUnits > 0) {
    return SourceLang.go;
  }
  if (numCppUnits >= numRustUnits &&
      numCppUnits >= numGoUnits &&
      numCppUnits > 0) {
    return SourceLang.cpp;
  }

  return SourceLang.unknown;
}
