// Copyright (c) 2019, 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:ffi';
import 'dart:io';

import 'package:expect/expect.dart';

import 'ffi_test_helpers.dart';

// void* mmap(void* addr, size_t length,
//            int prot, int flags,
//            int fd, off_t offset)
typedef MMapNative = Pointer<Uint8> Function(Pointer<Uint8> address, IntPtr len,
    IntPtr prot, IntPtr flags, IntPtr fd, IntPtr offset);
typedef MMap = Pointer<Uint8> Function(
    Pointer<Uint8> address, int len, int prot, int flags, int fd, int offset);
final mmap = processSymbols.lookupFunction<MMapNative, MMap>('mmap');

// int munmap(void *addr, size_t length)
typedef MUnMapNative = IntPtr Function(Pointer<Uint8> address, IntPtr len);
typedef MUnMap = int Function(Pointer<Uint8> address, int len);
final munmap = processSymbols.lookupFunction<MUnMapNative, MUnMap>('munmap');

final processSymbols = DynamicLibrary.process();

const int kProtRead = 1;
const int kProtWrite = 2;

const int kMapPrivate = 2;
const int kMapFixed = 16;
final int kMapAnonymous = Platform.isMacOS ? 0x1000 : 0x20;

const int kMapFailed = -1;

// On 32-bit platforms the upper 4 bytes should be ignored.
const int kIgnoreBytesPositive = 0x1122334400000000;
const int kIgnoreBytesNegative = 0xffddccbb00000000;

void swapBytes(
    Pointer<Uint8> memoryView, int indexOffset, int indexA, int indexB) {
  final int oldA = memoryView[indexOffset + indexA];
  memoryView[indexOffset + indexA] = memoryView[indexOffset + indexB];
  memoryView[indexOffset + indexB] = oldA;
}

void testLoadsAndStores(int indexOffset, Pointer<Uint8> memory) {
  for (int i = 0; i < 10; ++i) {
    memory[indexOffset + i] = 10 + i;
  }
  Expect.listEquals(<int>[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
      memory.offsetBy(indexOffset).asTypedList(10));

  for (int i = 0; i < 9; ++i) {
    swapBytes(memory, indexOffset + 0, i, i + 1);
  }
  Expect.listEquals(<int>[11, 12, 13, 14, 15, 16, 17, 18, 19, 10],
      memory.offsetBy(indexOffset).asTypedList(10));
  for (int i = 0; i < 9; ++i) {
    swapBytes(memory, indexOffset + kIgnoreBytesPositive, i, i + 1);
  }
  Expect.listEquals(<int>[12, 13, 14, 15, 16, 17, 18, 19, 10, 11],
      memory.offsetBy(indexOffset).asTypedList(10));
  for (int i = 0; i < 9; ++i) {
    swapBytes(memory, indexOffset + kIgnoreBytesNegative, i, i + 1);
  }
  Expect.listEquals(<int>[13, 14, 15, 16, 17, 18, 19, 10, 11, 12],
      memory.offsetBy(indexOffset).asTypedList(10));
}

void testOnHighOrLowMemory(Pointer<Uint8> memory, int indexOffset) {
  testLoadsAndStores(indexOffset, memory);
  testLoadsAndStores(indexOffset, memory.offsetBy(5));
  testLoadsAndStores(indexOffset, memory.offsetBy(-5));
  testLoadsAndStores(indexOffset, memory.offsetBy(kIgnoreBytesPositive + 5));
  testLoadsAndStores(indexOffset, memory.offsetBy(kIgnoreBytesNegative + 5));
  testLoadsAndStores(indexOffset, memory.offsetBy(kIgnoreBytesPositive - 5));
  testLoadsAndStores(indexOffset, memory.offsetBy(kIgnoreBytesNegative - 5));
  final m2 = Pointer<Uint8>.fromAddress(kIgnoreBytesPositive + memory.address);
  Expect.equals(memory, m2); //# 01: ok
  Expect.equals(memory.address, m2.address); //# 01: ok
  testLoadsAndStores(indexOffset, m2);
  final m3 = Pointer<Uint8>.fromAddress(kIgnoreBytesNegative + memory.address);
  Expect.equals(memory, m3); //# 01: ok
  Expect.equals(memory.address, m3.address); //# 01: ok
  testLoadsAndStores(indexOffset, m3);
}

const int kPageSize = 4096;

withMMapedAddress(
    Pointer<Uint8> fixedAddress, void fun(Pointer<Uint8> address)) {
  final result = mmap(fixedAddress, kPageSize, kProtRead | kProtWrite,
      kMapAnonymous | kMapFixed | kMapPrivate, 0, 0);
  if (result.address == kMapFailed) {
    throw 'Could not mmap @0x${fixedAddress.address.toRadixString(16)}!';
  }
  Expect.equals(fixedAddress, result); //# 01: ok
  Expect.equals(fixedAddress.address, result.address); //# 01: ok
  try {
    fun(result);
  } finally {
    if (munmap(result, kPageSize) != 0) {
      throw 'Failed to unmap memory!';
    }
  }
}

main() {
  final bool is32BitProcess = sizeOf<Pointer<Uint8>>() == 4;

  // User space processes usually have
  //   * the lower 3 GB available on Linux/Android on 32bit OS
  //   * full 4 GB available on Linux/Android on 64bit OS
  //   * full 4 GB available on MacOS
  // So we choose high and low addresses that fall into lower 3 GB.
  if (is32BitProcess && !Platform.isWindows) {
    final highMemoryAddress = Pointer<Uint8>.fromAddress(0xaaaa0000);
    final lowMemoryAddress = Pointer<Uint8>.fromAddress(0x11110000);
    withMMapedAddress(lowMemoryAddress, (Pointer<Uint8> lowMemory) {
      withMMapedAddress(highMemoryAddress, (Pointer<Uint8> highMemory) {
        testOnHighOrLowMemory(lowMemory, 2048);
        testOnHighOrLowMemory(highMemory, 2048);
        testOnHighOrLowMemory(
            lowMemory, 2048 + highMemory.address - lowMemory.address);
        testOnHighOrLowMemory(
            highMemory, 2048 + lowMemory.address - highMemory.address);
      });
    });
  }
}
