// Copyright 2019 The Flutter 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:io' show Directory;
import 'dart:async';

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';

const String kTemporaryPath = 'temporaryPath';
const String kApplicationSupportPath = 'applicationSupportPath';
const String kDownloadsPath = 'downloadsPath';
const String kLibraryPath = 'libraryPath';
const String kApplicationDocumentsPath = 'applicationDocumentsPath';
const String kExternalCachePath = 'externalCachePath';
const String kExternalStoragePath = 'externalStoragePath';

void main() {
  group('PathProvider', () {
    TestWidgetsFlutterBinding.ensureInitialized();

    setUp(() async {
      PathProviderPlatform.instance = MockPathProviderPlatform();
    });

    test('getTemporaryDirectory', () async {
      Directory? result = await getTemporaryDirectory();
      expect(result?.path, kTemporaryPath);
    });

    test('getApplicationSupportDirectory', () async {
      Directory? result = await getApplicationSupportDirectory();
      expect(result?.path, kApplicationSupportPath);
    });

    test('getLibraryDirectory', () async {
      Directory? result = await getLibraryDirectory();
      expect(result?.path, kLibraryPath);
    });

    test('getApplicationDocumentsDirectory', () async {
      Directory? result = await getApplicationDocumentsDirectory();
      expect(result?.path, kApplicationDocumentsPath);
    });

    test('getExternalStorageDirectory', () async {
      Directory? result = await getExternalStorageDirectory();
      expect(result?.path, kExternalStoragePath);
    });

    test('getExternalCacheDirectories', () async {
      List<Directory>? result = await getExternalCacheDirectories();
      expect(result?.length, 1);
      expect(result?.first.path, kExternalCachePath);
    });

    test('getExternalStorageDirectories', () async {
      List<Directory>? result = await getExternalStorageDirectories();
      expect(result?.length, 1);
      expect(result?.first.path, kExternalStoragePath);
    });

    test('getDownloadsDirectory', () async {
      Directory? result = await getDownloadsDirectory();
      expect(result?.path, kDownloadsPath);
    });
  });
}

class MockPathProviderPlatform extends Mock
    with MockPlatformInterfaceMixin
    implements PathProviderPlatform {
  Future<String> getTemporaryPath() async {
    return kTemporaryPath;
  }

  Future<String> getApplicationSupportPath() async {
    return kApplicationSupportPath;
  }

  Future<String> getLibraryPath() async {
    return kLibraryPath;
  }

  Future<String> getApplicationDocumentsPath() async {
    return kApplicationDocumentsPath;
  }

  Future<String> getExternalStoragePath() async {
    return kExternalStoragePath;
  }

  Future<List<String>> getExternalCachePaths() async {
    return <String>[kExternalCachePath];
  }

  Future<List<String>> getExternalStoragePaths({
    StorageDirectory? type,
  }) async {
    return <String>[kExternalStoragePath];
  }

  Future<String> getDownloadsPath() async {
    return kDownloadsPath;
  }
}
