// 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.

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

import 'package:path/path.dart' as path;
import 'package:expect/expect.dart';
import 'package:source_maps/source_maps.dart' hide SourceFile;
import 'package:compiler/src/apiimpl.dart';
import 'package:compiler/src/elements/elements.dart'
    show AstElement,
         ClassElement,
         CompilationUnitElement,
         Element,
         FunctionElement,
         LibraryElement,
         MemberElement;
import 'package:compiler/src/io/source_file.dart' show SourceFile;
import 'package:compiler/src/io/source_information.dart'
    show computeElementNameForSourceMaps;

validateSourceMap(Uri targetUri,
                  {Uri mainUri,
                   Position mainPosition,
                   CompilerImpl compiler}) {
  Uri mapUri = getMapUri(targetUri);
  List<String> targetLines = new File.fromUri(targetUri).readAsLinesSync();
  SingleMapping sourceMap = getSourceMap(mapUri);
  checkFileReferences(targetUri, mapUri, sourceMap);
  checkIndexReferences(targetLines, mapUri, sourceMap);
  checkRedundancy(sourceMap);
  if (compiler != null) {
    checkNames(targetUri, mapUri, sourceMap, compiler);
  }
  if (mainUri != null && mainPosition != null) {
    checkMainPosition(targetUri, targetLines ,sourceMap, mainUri, mainPosition);
  }
}

checkIndexReferences(List<String> targetLines,
                     Uri mapUri,
                     SingleMapping sourceMap) {
  int urlsLength = sourceMap.urls.length;
  List<List<String>> sources = new List(urlsLength);
  print('Reading sources');
  for (int i = 0; i < urlsLength; i++) {
    sources[i] = new File.fromUri(mapUri.resolve(sourceMap.urls[i])).
        readAsStringSync().split('\n');
  }

  sourceMap.lines.forEach((TargetLineEntry line) {
    Expect.isTrue(line.line >= 0);
    Expect.isTrue(line.line < targetLines.length);
    for (TargetEntry entry in line.entries) {
      int urlIndex = entry.sourceUrlId;

      // TODO(zarah): Entry columns sometimes point one or more characters too
      // far. Incomment this check when this is fixed.
      //
      // Expect.isTrue(entry.column < target[line.line].length);
      Expect.isTrue(entry.column >= 0);
      Expect.isTrue(urlIndex == null ||
          (urlIndex >= 0 && urlIndex < urlsLength));
      Expect.isTrue(entry.sourceLine == null ||
          (entry.sourceLine >= 0 &&
           entry.sourceLine < sources[urlIndex].length));
      Expect.isTrue(entry.sourceColumn == null ||
          (entry.sourceColumn >= 0 &&
           entry.sourceColumn < sources[urlIndex][entry.sourceLine].length));
      Expect.isTrue(entry.sourceNameId == null ||
          (entry.sourceNameId >= 0 &&
           entry.sourceNameId < sourceMap.names.length));
    }
  });
}

checkFileReferences(Uri targetUri, Uri mapUri, SingleMapping sourceMap) {
  Expect.equals(targetUri, mapUri.resolve(sourceMap.targetUrl));
  print('Checking sources');
  sourceMap.urls.forEach((String url) {
    Expect.isTrue(new File.fromUri(mapUri.resolve(url)).existsSync());
  });
}

checkRedundancy(SingleMapping sourceMap) {
  sourceMap.lines.forEach((TargetLineEntry line) {
    TargetEntry previous = null;
    for (TargetEntry next in line.entries) {
      if (previous != null) {
        Expect.isFalse(sameSourcePoint(previous, next),
            '$previous and $next are consecutive entries on line $line in the '
            'source map but point to same source locations');
      }
      previous = next;
    }
  });
}

checkNames(Uri targetUri, Uri mapUri,
           SingleMapping sourceMap, CompilerImpl compiler) {
  Map<Uri, CompilationUnitElement> compilationUnitMap = {};

  void mapCompilationUnits(LibraryElement library) {
    library.compilationUnits.forEach((CompilationUnitElement compilationUnit) {
      compilationUnitMap[compilationUnit.script.readableUri] = compilationUnit;
    });
  }

  compiler.libraryLoader.libraries.forEach((LibraryElement library) {
    mapCompilationUnits(library);
    if (library.patch != null) {
      mapCompilationUnits(library.patch);
    }
  });

  sourceMap.lines.forEach((TargetLineEntry line) {
    for (TargetEntry entry in line.entries) {
      if (entry.sourceNameId != null) {
        Uri uri = mapUri.resolve(sourceMap.urls[entry.sourceUrlId]);
        Position targetPosition =
            new Position(line.line, entry.column);
        Position sourcePosition =
            new Position(entry.sourceLine, entry.sourceColumn);
        String name = sourceMap.names[entry.sourceNameId];

        CompilationUnitElement compilationUnit = compilationUnitMap[uri];
        Expect.isNotNull(compilationUnit,
                         "No compilation unit found for $uri.");

        SourceFile sourceFile = compilationUnit.script.file;

        Position positionFromOffset(int offset) {
          int line = sourceFile.getLine(offset);
          int column = sourceFile.getColumn(line, offset);
          return new Position(line, column);
        }

        Interval intervalFromElement(AstElement element) {
          if (!element.hasNode) return null;

          var begin = element.node.getBeginToken().charOffset;
          var end = element.node.getEndToken();
          end = end.charOffset + end.charCount;
          return new Interval(positionFromOffset(begin),
                              positionFromOffset(end));
        }

        AstElement findInnermost(AstElement element) {
          bool isInsideElement(FunctionElement closure) {
            Element enclosing = closure;
            while (enclosing != null) {
              if (enclosing == element) return true;
              enclosing = enclosing.enclosingElement;
            }
            return false;
          }

          if (element is MemberElement) {
            MemberElement member = element;
            member.nestedClosures.forEach((closure) {
              var localFunction = closure.expression;
              Interval interval = intervalFromElement(localFunction);
              if (interval != null &&
                  interval.contains(sourcePosition) &&
                  isInsideElement(localFunction)) {
                element = localFunction;
              }
            });
          }
          return element;
        }

        void match(AstElement element) {
          Interval interval = intervalFromElement(element);
          if (interval != null && interval.contains(sourcePosition)) {
            AstElement innerElement = findInnermost(element);
            String expectedName =
                computeElementNameForSourceMaps(innerElement);
            if (name != expectedName) {
              // For the code
              //    (){}();
              //    ^
              // the indicated position is within the scope of the local
              // function but it is also the position for the invocation of it.
              // Allow name to be either from the local or from its calling
              // context.
              if (innerElement.isLocal && innerElement.isFunction) {
                var enclosingElement = innerElement.enclosingElement;
                String expectedName2 =
                    computeElementNameForSourceMaps(enclosingElement);
                Expect.isTrue(name == expectedName2,
                    "Unexpected name '${name}', "
                    "expected '${expectedName}' for $innerElement "
                    "or '${expectedName2}' for $enclosingElement.");
              } else {
                Expect.equals(expectedName, name,
                    "Unexpected name '${name}', "
                    "expected '${expectedName}' or for $innerElement.");
              }
            }
          }
        }

        compilationUnit.forEachLocalMember((AstElement element) {
          if (element.isClass) {
            ClassElement classElement = element;
            classElement.forEachLocalMember(match);
          } else {
            match(element);
          }
        });
      }
    }
  });
}

RegExp mainSignaturePrefix = new RegExp(r'main: \[?function\(');

// Check that the line pointing to by [mainPosition] in [mainUri] contains
// the main function signature.
checkMainPosition(Uri targetUri,
                  List<String> targetLines,
                  SingleMapping sourceMap,
                  Uri mainUri,
                  Position mainPosition) {
  bool mainPositionFound = false;
  sourceMap.lines.forEach((TargetLineEntry lineEntry) {
    lineEntry.entries.forEach((TargetEntry entry) {
      if (entry.sourceLine == null || entry.sourceUrlId == null) return;
      Uri sourceUri = targetUri.resolve(sourceMap.urls[entry.sourceUrlId]);
      if (sourceUri != mainUri) return;
      if (entry.sourceLine + 1 == mainPosition.line &&
          entry.sourceColumn + 1 == mainPosition.column) {
        Expect.isNotNull(entry.sourceNameId,
                         "Main position has no name.");
        String name = sourceMap.names[entry.sourceNameId];
        Expect.equals('main', name,
                      "Main position name is not '$name', not 'main'.");
        String line = targetLines[lineEntry.line];
        Expect.isTrue(line.contains(mainSignaturePrefix),
            "Line mapped to main position "
            "([${lineEntry.line + 1},${entry.column + 1}]) "
            "expected to contain '${mainSignaturePrefix.pattern}':\n$line\n");
        mainPositionFound = true;
      }
    });
  });
  Expect.isTrue(mainPositionFound,
                'No main position $mainPosition found in $mainUri');
}


sameSourcePoint(TargetEntry entry, TargetEntry otherEntry) {
  return
      (entry.sourceUrlId == otherEntry.sourceUrlId) &&
      (entry.sourceLine == otherEntry.sourceLine) &&
      (entry.sourceColumn == otherEntry.sourceColumn) &&
      (entry.sourceNameId == otherEntry.sourceNameId);
}

Uri getMapUri(Uri targetUri) {
  print('Accessing $targetUri');
  File targetFile = new File.fromUri(targetUri);
  Expect.isTrue(targetFile.existsSync(), "File '$targetUri' doesn't exist.");
  List<String> target = targetFile.readAsStringSync().split('\n');
  String mapReference = target[target.length - 2]; // #sourceMappingURL=<url>
  Expect.isTrue(mapReference.startsWith('//# sourceMappingURL='));
  String mapName = mapReference.substring(mapReference.indexOf('=') + 1);
  return targetUri.resolve(mapName);
}

SingleMapping getSourceMap(Uri mapUri) {
  print('Accessing $mapUri');
  File mapFile = new File.fromUri(mapUri);
  Expect.isTrue(mapFile.existsSync());
  return new SingleMapping.fromJson(
      JSON.decode(mapFile.readAsStringSync()));
}

copyDirectory(Directory sourceDir, Directory destinationDir) {
  sourceDir.listSync().forEach((FileSystemEntity element) {
    String newPath = path.join(destinationDir.path,
                               path.basename(element.path));
    if (element is File) {
      element.copySync(newPath);
    } else if (element is Directory) {
      Directory newDestinationDir = new Directory(newPath);
      newDestinationDir.createSync();
      copyDirectory(element, newDestinationDir);
    }
  });
}

Future<Directory> createTempDir() {
  return Directory.systemTemp
      .createTemp('sourceMap_test-')
      .then((Directory dir) {
    return dir;
  });
}

class Position {
  final int line;
  final int column;

  const Position(this.line, this.column);

  bool operator <=(Position other) {
    return line < other.line ||
           line == other.line && column <= other.column;
  }

  String toString() => '[${line + 1},${column + 1}]';
}

class Interval {
  final Position begin;
  final Position end;

  Interval(this.begin, this.end);

  bool contains(Position other) {
    return begin <= other && other <= end;
  }

  String toString() => '$begin-$end';
}