// Copyright 2018 The Chromium Authors. 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:typed_data';

import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class FakePlatformGoogleMap {
  FakePlatformGoogleMap(int id, Map<dynamic, dynamic> params) {
    cameraPosition = CameraPosition.fromMap(params['initialCameraPosition']);
    channel = MethodChannel(
        'plugins.flutter.io/google_maps_$id', const StandardMethodCodec());
    channel.setMockMethodCallHandler(onMethodCall);
    updateOptions(params['options']);
    updateMarkers(params);
    updatePolygons(params);
    updatePolylines(params);
    updateCircles(params);
    updateTileOverlays(Map.castFrom<dynamic, dynamic, String, dynamic>(params));
  }

  MethodChannel channel;

  CameraPosition cameraPosition;

  bool compassEnabled;

  bool mapToolbarEnabled;

  CameraTargetBounds cameraTargetBounds;

  MapType mapType;

  MinMaxZoomPreference minMaxZoomPreference;

  bool rotateGesturesEnabled;

  bool scrollGesturesEnabled;

  bool tiltGesturesEnabled;

  bool zoomGesturesEnabled;

  bool zoomControlsEnabled;

  bool liteModeEnabled;

  bool trackCameraPosition;

  bool myLocationEnabled;

  bool trafficEnabled;

  bool buildingsEnabled;

  bool myLocationButtonEnabled;

  List<dynamic> padding;

  Set<MarkerId> markerIdsToRemove;

  Set<Marker> markersToAdd;

  Set<Marker> markersToChange;

  Set<PolygonId> polygonIdsToRemove;

  Set<Polygon> polygonsToAdd;

  Set<Polygon> polygonsToChange;

  Set<PolylineId> polylineIdsToRemove;

  Set<Polyline> polylinesToAdd;

  Set<Polyline> polylinesToChange;

  Set<CircleId> circleIdsToRemove;

  Set<Circle> circlesToAdd;

  Set<Circle> circlesToChange;

  Set<TileOverlayId> tileOverlayIdsToRemove;

  Set<TileOverlay> tileOverlaysToAdd;

  Set<TileOverlay> tileOverlaysToChange;

  Future<dynamic> onMethodCall(MethodCall call) {
    switch (call.method) {
      case 'map#update':
        updateOptions(call.arguments['options']);
        return Future<void>.sync(() {});
      case 'markers#update':
        updateMarkers(call.arguments);
        return Future<void>.sync(() {});
      case 'polygons#update':
        updatePolygons(call.arguments);
        return Future<void>.sync(() {});
      case 'polylines#update':
        updatePolylines(call.arguments);
        return Future<void>.sync(() {});
      case 'tileOverlays#update':
        updateTileOverlays(
            Map.castFrom<dynamic, dynamic, String, dynamic>(call.arguments));
        return Future<void>.sync(() {});
      case 'circles#update':
        updateCircles(call.arguments);
        return Future<void>.sync(() {});
      default:
        return Future<void>.sync(() {});
    }
  }

  void updateMarkers(Map<dynamic, dynamic> markerUpdates) {
    if (markerUpdates == null) {
      return;
    }
    markersToAdd = _deserializeMarkers(markerUpdates['markersToAdd']);
    markerIdsToRemove =
        _deserializeMarkerIds(markerUpdates['markerIdsToRemove']);
    markersToChange = _deserializeMarkers(markerUpdates['markersToChange']);
  }

  Set<MarkerId> _deserializeMarkerIds(List<dynamic> markerIds) {
    if (markerIds == null) {
      // TODO(iskakaushik): Remove this when collection literals makes it to stable.
      // https://github.com/flutter/flutter/issues/28312
      // ignore: prefer_collection_literals
      return Set<MarkerId>();
    }
    return markerIds.map((dynamic markerId) => MarkerId(markerId)).toSet();
  }

  Set<Marker> _deserializeMarkers(dynamic markers) {
    if (markers == null) {
      // TODO(iskakaushik): Remove this when collection literals makes it to stable.
      // https://github.com/flutter/flutter/issues/28312
      // ignore: prefer_collection_literals
      return Set<Marker>();
    }
    final List<dynamic> markersData = markers;
    // TODO(iskakaushik): Remove this when collection literals makes it to stable.
    // https://github.com/flutter/flutter/issues/28312
    // ignore: prefer_collection_literals
    final Set<Marker> result = Set<Marker>();
    for (Map<dynamic, dynamic> markerData in markersData) {
      final String markerId = markerData['markerId'];
      final double alpha = markerData['alpha'];
      final bool draggable = markerData['draggable'];
      final bool visible = markerData['visible'];

      final dynamic infoWindowData = markerData['infoWindow'];
      InfoWindow infoWindow = InfoWindow.noText;
      if (infoWindowData != null) {
        final Map<dynamic, dynamic> infoWindowMap = infoWindowData;
        infoWindow = InfoWindow(
          title: infoWindowMap['title'],
          snippet: infoWindowMap['snippet'],
        );
      }

      result.add(Marker(
        markerId: MarkerId(markerId),
        draggable: draggable,
        visible: visible,
        infoWindow: infoWindow,
        alpha: alpha,
      ));
    }

    return result;
  }

  void updatePolygons(Map<dynamic, dynamic> polygonUpdates) {
    if (polygonUpdates == null) {
      return;
    }
    polygonsToAdd = _deserializePolygons(polygonUpdates['polygonsToAdd']);
    polygonIdsToRemove =
        _deserializePolygonIds(polygonUpdates['polygonIdsToRemove']);
    polygonsToChange = _deserializePolygons(polygonUpdates['polygonsToChange']);
  }

  Set<PolygonId> _deserializePolygonIds(List<dynamic> polygonIds) {
    if (polygonIds == null) {
      // TODO(iskakaushik): Remove this when collection literals makes it to stable.
      // https://github.com/flutter/flutter/issues/28312
      // ignore: prefer_collection_literals
      return Set<PolygonId>();
    }
    return polygonIds.map((dynamic polygonId) => PolygonId(polygonId)).toSet();
  }

  Set<Polygon> _deserializePolygons(dynamic polygons) {
    if (polygons == null) {
      // TODO(iskakaushik): Remove this when collection literals makes it to stable.
      // https://github.com/flutter/flutter/issues/28312
      // ignore: prefer_collection_literals
      return Set<Polygon>();
    }
    final List<dynamic> polygonsData = polygons;
    // TODO(iskakaushik): Remove this when collection literals makes it to stable.
    // https://github.com/flutter/flutter/issues/28312
    // ignore: prefer_collection_literals
    final Set<Polygon> result = Set<Polygon>();
    for (Map<dynamic, dynamic> polygonData in polygonsData) {
      final String polygonId = polygonData['polygonId'];
      final bool visible = polygonData['visible'];
      final bool geodesic = polygonData['geodesic'];
      final List<LatLng> points = _deserializePoints(polygonData['points']);
      final List<List<LatLng>> holes = _deserializeHoles(polygonData['holes']);

      result.add(Polygon(
        polygonId: PolygonId(polygonId),
        visible: visible,
        geodesic: geodesic,
        points: points,
        holes: holes,
      ));
    }

    return result;
  }

  List<LatLng> _deserializePoints(List<dynamic> points) {
    return points.map<LatLng>((dynamic list) {
      return LatLng(list[0], list[1]);
    }).toList();
  }

  List<List<LatLng>> _deserializeHoles(List<dynamic> holes) {
    return holes.map<List<LatLng>>((dynamic hole) {
      return hole.map<LatLng>((dynamic list) {
        return LatLng(list[0], list[1]);
      }).toList();
    }).toList();
  }

  void updatePolylines(Map<dynamic, dynamic> polylineUpdates) {
    if (polylineUpdates == null) {
      return;
    }
    polylinesToAdd = _deserializePolylines(polylineUpdates['polylinesToAdd']);
    polylineIdsToRemove =
        _deserializePolylineIds(polylineUpdates['polylineIdsToRemove']);
    polylinesToChange =
        _deserializePolylines(polylineUpdates['polylinesToChange']);
  }

  Set<PolylineId> _deserializePolylineIds(List<dynamic> polylineIds) {
    if (polylineIds == null) {
      // TODO(iskakaushik): Remove this when collection literals makes it to stable.
      // https://github.com/flutter/flutter/issues/28312
      // ignore: prefer_collection_literals
      return Set<PolylineId>();
    }
    return polylineIds
        .map((dynamic polylineId) => PolylineId(polylineId))
        .toSet();
  }

  Set<Polyline> _deserializePolylines(dynamic polylines) {
    if (polylines == null) {
      // TODO(iskakaushik): Remove this when collection literals makes it to stable.
      // https://github.com/flutter/flutter/issues/28312
      // ignore: prefer_collection_literals
      return Set<Polyline>();
    }
    final List<dynamic> polylinesData = polylines;
    // TODO(iskakaushik): Remove this when collection literals makes it to stable.
    // https://github.com/flutter/flutter/issues/28312
    // ignore: prefer_collection_literals
    final Set<Polyline> result = Set<Polyline>();
    for (Map<dynamic, dynamic> polylineData in polylinesData) {
      final String polylineId = polylineData['polylineId'];
      final bool visible = polylineData['visible'];
      final bool geodesic = polylineData['geodesic'];
      final List<LatLng> points = _deserializePoints(polylineData['points']);

      result.add(Polyline(
        polylineId: PolylineId(polylineId),
        visible: visible,
        geodesic: geodesic,
        points: points,
      ));
    }

    return result;
  }

  void updateCircles(Map<dynamic, dynamic> circleUpdates) {
    if (circleUpdates == null) {
      return;
    }
    circlesToAdd = _deserializeCircles(circleUpdates['circlesToAdd']);
    circleIdsToRemove =
        _deserializeCircleIds(circleUpdates['circleIdsToRemove']);
    circlesToChange = _deserializeCircles(circleUpdates['circlesToChange']);
  }

  void updateTileOverlays(Map<String, dynamic> updateTileOverlayUpdates) {
    if (updateTileOverlayUpdates == null) {
      return;
    }
    final List<Map<dynamic, dynamic>> tileOverlaysToAddList =
        updateTileOverlayUpdates['tileOverlaysToAdd'] != null
            ? List.castFrom<dynamic, Map<dynamic, dynamic>>(
                updateTileOverlayUpdates['tileOverlaysToAdd'])
            : null;
    final List<String> tileOverlayIdsToRemoveList =
        updateTileOverlayUpdates['tileOverlayIdsToRemove'] != null
            ? List.castFrom<dynamic, String>(
                updateTileOverlayUpdates['tileOverlayIdsToRemove'])
            : null;
    final List<Map<dynamic, dynamic>> tileOverlaysToChangeList =
        updateTileOverlayUpdates['tileOverlaysToChange'] != null
            ? List.castFrom<dynamic, Map<dynamic, dynamic>>(
                updateTileOverlayUpdates['tileOverlaysToChange'])
            : null;
    tileOverlaysToAdd = _deserializeTileOverlays(tileOverlaysToAddList);
    tileOverlayIdsToRemove =
        _deserializeTileOverlayIds(tileOverlayIdsToRemoveList);
    tileOverlaysToChange = _deserializeTileOverlays(tileOverlaysToChangeList);
  }

  Set<CircleId> _deserializeCircleIds(List<dynamic> circleIds) {
    if (circleIds == null) {
      // TODO(iskakaushik): Remove this when collection literals makes it to stable.
      // https://github.com/flutter/flutter/issues/28312
      // ignore: prefer_collection_literals
      return Set<CircleId>();
    }
    return circleIds.map((dynamic circleId) => CircleId(circleId)).toSet();
  }

  Set<Circle> _deserializeCircles(dynamic circles) {
    if (circles == null) {
      // TODO(iskakaushik): Remove this when collection literals makes it to stable.
      // https://github.com/flutter/flutter/issues/28312
      // ignore: prefer_collection_literals
      return Set<Circle>();
    }
    final List<dynamic> circlesData = circles;
    // TODO(iskakaushik): Remove this when collection literals makes it to stable.
    // https://github.com/flutter/flutter/issues/28312
    // ignore: prefer_collection_literals
    final Set<Circle> result = Set<Circle>();
    for (Map<dynamic, dynamic> circleData in circlesData) {
      final String circleId = circleData['circleId'];
      final bool visible = circleData['visible'];
      final double radius = circleData['radius'];

      result.add(Circle(
        circleId: CircleId(circleId),
        visible: visible,
        radius: radius,
      ));
    }

    return result;
  }

  Set<TileOverlayId> _deserializeTileOverlayIds(List<String> tileOverlayIds) {
    if (tileOverlayIds == null || tileOverlayIds.isEmpty) {
      // TODO(iskakaushik): Remove this when collection literals makes it to stable.
      // https://github.com/flutter/flutter/issues/28312
      // ignore: prefer_collection_literals
      return Set<TileOverlayId>();
    }
    return tileOverlayIds
        .map((String tileOverlayId) => TileOverlayId(tileOverlayId))
        .toSet();
  }

  Set<TileOverlay> _deserializeTileOverlays(
      List<Map<dynamic, dynamic>> tileOverlays) {
    if (tileOverlays == null || tileOverlays.isEmpty) {
      // TODO(iskakaushik): Remove this when collection literals makes it to stable.
      // https://github.com/flutter/flutter/issues/28312
      // ignore: prefer_collection_literals
      return Set<TileOverlay>();
    }
    // TODO(iskakaushik): Remove this when collection literals makes it to stable.
    // https://github.com/flutter/flutter/issues/28312
    // ignore: prefer_collection_literals
    final Set<TileOverlay> result = Set<TileOverlay>();
    for (Map<dynamic, dynamic> tileOverlayData in tileOverlays) {
      final String tileOverlayId = tileOverlayData['tileOverlayId'];
      final bool fadeIn = tileOverlayData['fadeIn'];
      final double transparency = tileOverlayData['transparency'];
      final int zIndex = tileOverlayData['zIndex'];
      final bool visible = tileOverlayData['visible'];

      result.add(TileOverlay(
        tileOverlayId: TileOverlayId(tileOverlayId),
        fadeIn: fadeIn,
        transparency: transparency,
        zIndex: zIndex,
        visible: visible,
      ));
    }

    return result;
  }

  void updateOptions(Map<dynamic, dynamic> options) {
    if (options.containsKey('compassEnabled')) {
      compassEnabled = options['compassEnabled'];
    }
    if (options.containsKey('mapToolbarEnabled')) {
      mapToolbarEnabled = options['mapToolbarEnabled'];
    }
    if (options.containsKey('cameraTargetBounds')) {
      final List<dynamic> boundsList = options['cameraTargetBounds'];
      cameraTargetBounds = boundsList[0] == null
          ? CameraTargetBounds.unbounded
          : CameraTargetBounds(LatLngBounds.fromList(boundsList[0]));
    }
    if (options.containsKey('mapType')) {
      mapType = MapType.values[options['mapType']];
    }
    if (options.containsKey('minMaxZoomPreference')) {
      final List<dynamic> minMaxZoomList = options['minMaxZoomPreference'];
      minMaxZoomPreference =
          MinMaxZoomPreference(minMaxZoomList[0], minMaxZoomList[1]);
    }
    if (options.containsKey('rotateGesturesEnabled')) {
      rotateGesturesEnabled = options['rotateGesturesEnabled'];
    }
    if (options.containsKey('scrollGesturesEnabled')) {
      scrollGesturesEnabled = options['scrollGesturesEnabled'];
    }
    if (options.containsKey('tiltGesturesEnabled')) {
      tiltGesturesEnabled = options['tiltGesturesEnabled'];
    }
    if (options.containsKey('trackCameraPosition')) {
      trackCameraPosition = options['trackCameraPosition'];
    }
    if (options.containsKey('zoomGesturesEnabled')) {
      zoomGesturesEnabled = options['zoomGesturesEnabled'];
    }
    if (options.containsKey('zoomControlsEnabled')) {
      zoomControlsEnabled = options['zoomControlsEnabled'];
    }
    if (options.containsKey('liteModeEnabled')) {
      liteModeEnabled = options['liteModeEnabled'];
    }
    if (options.containsKey('myLocationEnabled')) {
      myLocationEnabled = options['myLocationEnabled'];
    }
    if (options.containsKey('myLocationButtonEnabled')) {
      myLocationButtonEnabled = options['myLocationButtonEnabled'];
    }
    if (options.containsKey('trafficEnabled')) {
      trafficEnabled = options['trafficEnabled'];
    }
    if (options.containsKey('buildingsEnabled')) {
      buildingsEnabled = options['buildingsEnabled'];
    }
    if (options.containsKey('padding')) {
      padding = options['padding'];
    }
  }
}

class FakePlatformViewsController {
  FakePlatformGoogleMap lastCreatedView;

  Future<dynamic> fakePlatformViewsMethodHandler(MethodCall call) {
    switch (call.method) {
      case 'create':
        final Map<dynamic, dynamic> args = call.arguments;
        final Map<dynamic, dynamic> params = _decodeParams(args['params']);
        lastCreatedView = FakePlatformGoogleMap(
          args['id'],
          params,
        );
        return Future<int>.sync(() => 1);
      default:
        return Future<void>.sync(() {});
    }
  }

  void reset() {
    lastCreatedView = null;
  }
}

Map<dynamic, dynamic> _decodeParams(Uint8List paramsMessage) {
  final ByteBuffer buffer = paramsMessage.buffer;
  final ByteData messageBytes = buffer.asByteData(
    paramsMessage.offsetInBytes,
    paramsMessage.lengthInBytes,
  );
  return const StandardMessageCodec().decodeMessage(messageBytes);
}
