// 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 LibraryElement,
         CompilationUnitElement,
         ClassElement,
         AstElement;
import 'package:compiler/src/io/source_file.dart' show SourceFile;

validateSourceMap(Uri targetUri,
                  {Uri mainUri,
                   Position mainPosition,
                   Compiler 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, Compiler 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));
        }

        void match(AstElement element) {
          Interval interval = intervalFromElement(element);
          if (interval != null && interval.contains(sourcePosition)) {
            if (name != 'call') {
              // TODO(johnniwinther): Check closures.
              Expect.equals(element.name, name);
            } else if (name != element.name) {
              print("${targetUri}$targetPosition:\n"
                    "Name '$name' does not match element $element in "
                    "${sourceFile.filename}$sourcePosition.");
            }
          }
        }

        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,$column]';
}

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';
}