// Copyright (c) 2014, 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.

library dartdoc.model_utils;

import 'dart:collection';
import 'dart:convert';
import 'dart:io';

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:collection/collection.dart';
import 'package:dartdoc/src/model.dart';
import 'package:quiver/core.dart';

import 'config.dart';

final Map<String, String> _fileContents = <String, String>{};

/// Remove elements that aren't documented.
Iterable<T> filterNonDocumented<T extends Documentable>(
    Iterable<T> maybeDocumentedItems) {
  return maybeDocumentedItems.where((me) => me.isDocumented);
}

/// Returns an iterable containing only public elements from [privacyItems].
Iterable<T> filterNonPublic<T extends Privacy>(Iterable<T> privacyItems) {
  return privacyItems.where((me) => me.isPublic);
}

/// Finds canonical classes for all classes in the iterable, if possible.
/// If a canonical class can not be found, returns the original class.
Iterable<Class> findCanonicalFor(Iterable<Class> classes) {
  return classes.map(
      (c) => c.package.findCanonicalModelElementFor(c.element) as Class ?? c);
}

String getFileContentsFor(Element e) {
  var location = e.source.fullName;
  if (!_fileContents.containsKey(location)) {
    var contents = new File(location).readAsStringSync();
    _fileContents.putIfAbsent(location, () => contents);
  }
  return _fileContents[location];
}

Iterable<LibraryElement> getRequiredSdkLibraries(
    DartSdk sdk, AnalysisContext context) {
  var requiredLibs = sdk.sdkLibraries
      .where((sdkLib) => sdkLib.shortName == 'dart:_interceptors');
  final Set<LibraryElement> allLibraryElements = new Set();
  for (var sdkLib in requiredLibs) {
    Source source = sdk.mapDartUri(sdkLib.shortName);
    allLibraryElements.add(context.computeLibraryElement(source));
  }
  return allLibraryElements;
}

bool isInExportedLibraries(
    List<LibraryElement> libraries, LibraryElement library) {
  return libraries
      .any((lib) => lib == library || lib.exportedLibraries.contains(library));
}

final RegExp slashes = new RegExp('[\/]');
bool hasPrivateName(Element e) {
  if (e.name.startsWith('_')) {
    return true;
  }
  // GenericFunctionTypeElements have the name we care about in the enclosing
  // element.
  if (e is GenericFunctionTypeElement) {
    if (e.enclosingElement.name.startsWith('_')) {
      return true;
    }
  }
  if (e is LibraryElement &&
      (e.identifier.startsWith('dart:_') ||
          ['dart:nativewrappers'].contains(e.identifier))) {
    return true;
  }
  if (e is LibraryElement) {
    List<String> locationParts = e.location.components[0].split(slashes);
    // TODO(jcollins-g): Implement real cross package detection
    if (locationParts.length >= 2 &&
        locationParts[0].startsWith('package:') &&
        locationParts[1] == 'src') return true;
  }
  return false;
}

bool hasPublicName(Element e) => !hasPrivateName(e);

/// Strip leading dartdoc comments from the given source code.
String stripDartdocCommentsFromSource(String source) {
  String remainer = source.trimLeft();
  HtmlEscape sanitizer = const HtmlEscape();
  bool lineComments = remainer.startsWith('///') ||
      remainer.startsWith(sanitizer.convert('///'));
  bool blockComments = remainer.startsWith('/**') ||
      remainer.startsWith(sanitizer.convert('/**'));

  return source.split('\n').where((String line) {
    if (lineComments) {
      if (line.startsWith('///') || line.startsWith(sanitizer.convert('///'))) {
        return false;
      }
      lineComments = false;
      return true;
    } else if (blockComments) {
      if (line.contains('*/') || line.contains(sanitizer.convert('*/'))) {
        blockComments = false;
        return false;
      }
      if (line.startsWith('/**') || line.startsWith(sanitizer.convert('/**'))) {
        return false;
      }
      return false;
    }

    return true;
  }).join('\n');
}

/// Strip the common indent from the given source fragment.
String stripIndentFromSource(String source) {
  String remainer = source.trimLeft();
  String indent = source.substring(0, source.length - remainer.length);
  return source.split('\n').map((line) {
    line = line.trimRight();
    return line.startsWith(indent) ? line.substring(indent.length) : line;
  }).join('\n');
}

/// Add links to crossdart.info to the given source fragment
String crossdartifySource(
    Map<String, Map<String, List<Map<String, dynamic>>>> json,
    String source,
    Element element,
    int start) {
  var sanitizer = const HtmlEscape();
  String newSource;
  if (json.isNotEmpty) {
    var node = element.computeNode();
    var file = element.source.fullName
        .replaceAll("${config.inputDir.path}${Platform.pathSeparator}", "");
    var filesData = json[file];
    if (filesData != null) {
      var data = filesData["references"]
          .where((r) => r["offset"] >= start && r["end"] <= node.end);
      if (data.isNotEmpty) {
        var previousStop = 0;
        var stringBuffer = new StringBuffer();
        for (var item in data) {
          stringBuffer.write(sanitizer
              .convert(source.substring(previousStop, item["offset"] - start)));
          stringBuffer
              .write("<a class='crossdart-link' href='${item["remotePath"]}'>");
          stringBuffer.write(sanitizer.convert(
              source.substring(item["offset"] - start, item["end"] - start)));
          stringBuffer.write("</a>");
          previousStop = item["end"] - start;
        }
        stringBuffer.write(
            sanitizer.convert(source.substring(previousStop, source.length)));

        newSource = stringBuffer.toString();
      }
    }
  }
  if (newSource == null) {
    newSource = sanitizer.convert(source);
  }
  return newSource;
}

/// An UnmodifiableListView that computes equality and hashCode based on the
/// equality and hashCode of its contained objects.
class _HashableList {
  final List _source;
  int _hashCache;
  _HashableList(this._source);

  @override
  bool operator ==(other) {
    if (other is _HashableList) {
      if (_source.length == other._source.length) {
        for (var index = 0; index < _source.length; ++index) {
          if (_source[index] != other._source[index]) return false;
        }
        return true;
      }
    }
    return false;
  }

  @override
  get hashCode => _hashCache ??= hashObjects(_source);
}

/// Like [Memoizer], except in checked mode will validate that the value of the
/// memoized function is unchanging using [DeepCollectionEquality].  Still
/// returns the cached value assuming the assertion passes.
class ValidatingMemoizer extends Memoizer {
  bool _assert_on_difference = false;

  ValidatingMemoizer() : super() {
    // Assignment within assert to take advantage of the expression only
    // being executed in checked mode.
    assert(_assert_on_difference = true);
    invalidateMemos();
  }

  /// In checked mode and when constructed with assert_on_difference == true,
  /// validate that the return value from f() equals the memoized value.
  /// Otherwise, a wrapper around putIfAbsent.
  @override
  R _cacheIfAbsent<R>(_HashableList key, R Function() f) {
    if (_assert_on_difference) {
      if (_memoizationTable.containsKey(key)) {
        R value = f();
        if (!new DeepCollectionEquality()
            .equals(value, _memoizationTable[key])) {
          throw new AssertionError('${value} != $_memoizationTable[key]');
        }
      }
    }
    return super._cacheIfAbsent(key, f);
  }
}

/// A basic Memoizer class.  Instantiate as a member variable, extend, or use
/// as a mixin to track object-specific cached values, or instantiate directly
/// to track other values.
///
/// For all methods in this class, the parameter [f] must be a tear-off method
/// or top level function (not an inline closure) for memoization to work.
/// [Memoizer] depends on the equality operator on the given function to detect
/// when we are calling the same function.
///
/// Use:
///
/// ```dart
/// String aTestFunction(String greeting, String name) => "${greeting}, ${name}";
/// int aSlowFunction() { doSome(); return expensiveCalculations(); }
///
/// myMemoizer.memoized2(aTestFunction, "Hello, "world");
/// myMemoizer.memoized(aSlowFunction);
/// ```
///
/// *Not*:
///
/// ```dart
/// String aTestFunction(String greeting, String name) => "${greeting}, ${name}";
///
/// myMemoizer.memoized2((a, b) => aTestFunction(a, b), "Hello", "world");
/// myMemoizer.memoized(() => aSlowFunction());;
/// ```
class Memoizer {
  /// Map of a function and its positional parameters (if any), to a value.
  final Map<_HashableList, dynamic> _memoizationTable = new HashMap();

  /// Reset the memoization table, forcing calls of the underlying functions.
  void invalidateMemos() {
    _memoizationTable.clear();
  }

  /// A wrapper around putIfAbsent, exposed to allow overrides.
  R _cacheIfAbsent<R>(_HashableList key, R Function() f) {
    return _memoizationTable.putIfAbsent(key, f);
  }

  /// Calls and caches the return value of [f]() if not in the cache, then
  /// returns the cached value of [f]().
  R memoized<R>(Function f, {String altKey}) {
    Object obj = altKey ?? f;
    _HashableList key = new _HashableList([obj]);
    return _cacheIfAbsent(key, f);
  }

  /// Calls and caches the return value of [f]([param1]) if not in the cache, then
  /// returns the cached value of [f]([param1]).
  R memoized1<R, A>(R Function(A) f, A param1) {
    _HashableList key = new _HashableList([f, param1]);
    return _cacheIfAbsent(key, () => f(param1));
  }

  /// Calls and caches the return value of [f]([param1], [param2]) if not in the
  /// cache, then returns the cached value of [f]([param1], [param2]).
  R memoized2<R, A, B>(R Function(A, B) f, A param1, B param2) {
    _HashableList key = new _HashableList([f, param1, param2]);
    return _cacheIfAbsent(key, () => f(param1, param2));
  }

  /// Calls and caches the return value of [f]([param1], [param2], [param3]) if
  /// not in the cache, then returns the cached value of [f]([param1],
  /// [param2], [param3]).
  R memoized3<R, A, B, C>(R Function(A, B, C) f, A param1, B param2, C param3) {
    _HashableList key = new _HashableList([f, param1, param2, param3]);
    return _cacheIfAbsent(key, () => f(param1, param2, param3));
  }

  /// Calls and caches the return value of [f]([param1], [param2], [param3],
  /// [param4]) if not in the cache, then returns the cached value of
  /// [f]([param1], [param2], [param3], [param4]).
  R memoized4<R, A, B, C, D>(
      R Function(A, B, C, D) f, A param1, B param2, C param3, D param4) {
    _HashableList key = new _HashableList([f, param1, param2, param3, param4]);
    return _cacheIfAbsent(key, () => f(param1, param2, param3, param4));
  }

  /// Calls and caches the return value of [f]([param1], [param2], [param3],
  /// [param4], [param5]) if not in the cache, then returns the cached value of [f](
  /// [param1], [param2], [param3], [param4], [param5]).
  R memoized5<R, A, B, C, D, E>(R Function(A, B, C, D, E) f, A param1, B param2,
      C param3, D param4, E param5) {
    _HashableList key =
        new _HashableList([f, param1, param2, param3, param4, param5]);
    return _cacheIfAbsent(key, () => f(param1, param2, param3, param4, param5));
  }

  /// Calls and caches the return value of [f]([param1], [param2], [param3],
  /// [param4], [param5], [param6]) if not in the cache, then returns the cached
  /// value of [f]([param1], [param2], [param3], [param4], [param5], [param6]).
  R memoized6<R, A, B, C, D, E, F>(R Function(A, B, C, D, E, F) f, A param1,
      B param2, C param3, D param4, E param5, F param6) {
    _HashableList key =
        new _HashableList([f, param1, param2, param3, param4, param5, param6]);
    return _cacheIfAbsent(
        key, () => f(param1, param2, param3, param4, param5, param6));
  }

  /// Calls and caches the return value of [f]([param1], [param2], [param3],
  /// [param4], [param5], [param6], [param7]) if not in the cache, then returns
  /// the cached value of [f]([param1], [param2], [param3], [param4], [param5],
  /// [param6], [param7]).
  R memoized7<R, A, B, C, D, E, F, G>(R Function(A, B, C, D, E, F, G) f,
      A param1, B param2, C param3, D param4, E param5, F param6, G param7) {
    _HashableList key = new _HashableList(
        [f, param1, param2, param3, param4, param5, param6, param7]);
    return _cacheIfAbsent(
        key, () => f(param1, param2, param3, param4, param5, param6, param7));
  }

  /// Calls and caches the return value of [f]([param1], [param2], [param3],
  /// [param4], [param5], [param6], [param7], [param8]) if not in the cache,
  /// then returns the cached value of [f]([param1], [param2], [param3],
  /// [param4], [param5], [param6], [param7], [param8]).
  R memoized8<R, A, B, C, D, E, F, G, H>(
      R Function(A, B, C, D, E, F, G, H) f,
      A param1,
      B param2,
      C param3,
      D param4,
      E param5,
      F param6,
      G param7,
      H param8) {
    _HashableList key = new _HashableList(
        [f, param1, param2, param3, param4, param5, param6, param7, param8]);
    return _cacheIfAbsent(
        key,
        () =>
            f(param1, param2, param3, param4, param5, param6, param7, param8));
  }
}
