// Copyright 2013 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 'package:file/memory.dart';
import 'package:flutter_migrate/src/base/file_system.dart';
import 'package:flutter_migrate/src/base/logger.dart';
import 'package:flutter_migrate/src/flutter_project_metadata.dart';

import 'src/common.dart';

void main() {
  late FileSystem fileSystem;
  late BufferLogger logger;
  late File metadataFile;

  setUp(() {
    fileSystem = MemoryFileSystem.test();
    logger = BufferLogger.test();
    metadataFile = fileSystem.file('.metadata');
  });

  testWithoutContext(
      'project metadata fields are empty when file does not exist', () {
    final FlutterProjectMetadata projectMetadata =
        FlutterProjectMetadata(metadataFile, logger);
    expect(projectMetadata.projectType, isNull);
    expect(projectMetadata.versionChannel, isNull);
    expect(projectMetadata.versionRevision, isNull);

    expect(logger.traceText, contains('No .metadata file found at .metadata'));
  });

  testWithoutContext('project metadata fields are empty when file is empty',
      () {
    metadataFile.createSync();
    final FlutterProjectMetadata projectMetadata =
        FlutterProjectMetadata(metadataFile, logger);
    expect(projectMetadata.projectType, isNull);
    expect(projectMetadata.versionChannel, isNull);
    expect(projectMetadata.versionRevision, isNull);

    expect(logger.traceText,
        contains('.metadata file at .metadata was empty or malformed.'));
  });

  testWithoutContext(
      'project metadata fields are empty when file is not valid yaml', () {
    metadataFile.writeAsStringSync(' channel: @something');
    final FlutterProjectMetadata projectMetadata =
        FlutterProjectMetadata(metadataFile, logger);
    expect(projectMetadata.projectType, isNull);
    expect(projectMetadata.versionChannel, isNull);
    expect(projectMetadata.versionRevision, isNull);

    expect(logger.traceText,
        contains('.metadata file at .metadata was empty or malformed.'));
  });

  testWithoutContext('projectType is populated when version is null', () {
    metadataFile
      ..createSync()
      ..writeAsStringSync('''
version:
project_type: plugin
      ''');
    final FlutterProjectMetadata projectMetadata =
        FlutterProjectMetadata(metadataFile, logger);
    expect(projectMetadata.projectType, FlutterProjectType.plugin);
    expect(projectMetadata.versionChannel, isNull);
    expect(projectMetadata.versionRevision, isNull);

    expect(
        logger.traceText,
        contains(
            'The value of key `version` in .metadata was expected to be YamlMap but was Null'));
  });

  testWithoutContext('projectType is populated when version is malformed', () {
    metadataFile
      ..createSync()
      ..writeAsStringSync('''
version: STRING INSTEAD OF MAP
project_type: plugin
      ''');
    final FlutterProjectMetadata projectMetadata =
        FlutterProjectMetadata(metadataFile, logger);
    expect(projectMetadata.projectType, FlutterProjectType.plugin);
    expect(projectMetadata.versionChannel, isNull);
    expect(projectMetadata.versionRevision, isNull);

    expect(
        logger.traceText,
        contains(
            'The value of key `version` in .metadata was expected to be YamlMap but was String'));
  });

  testWithoutContext('version is populated when projectType is malformed', () {
    metadataFile
      ..createSync()
      ..writeAsStringSync('''
version:
  revision: b59b226a49391949247e3d6122e34bb001049ae4
  channel: stable
project_type: {}
      ''');
    final FlutterProjectMetadata projectMetadata =
        FlutterProjectMetadata(metadataFile, logger);
    expect(projectMetadata.projectType, isNull);
    expect(projectMetadata.versionChannel, 'stable');
    expect(projectMetadata.versionRevision,
        'b59b226a49391949247e3d6122e34bb001049ae4');

    expect(
        logger.traceText,
        contains(
            'The value of key `project_type` in .metadata was expected to be String but was YamlMap'));
  });

  testWithoutContext('migrate config is populated when version is malformed',
      () {
    metadataFile
      ..createSync()
      ..writeAsStringSync('''
version: STRING INSTEAD OF MAP
project_type: {}

migration:
  platforms:
    - platform: root
      create_revision: abcdefg
      base_revision: baserevision

  unmanaged_files:
    - 'file1'
      ''');
    final FlutterProjectMetadata projectMetadata =
        FlutterProjectMetadata(metadataFile, logger);
    expect(projectMetadata.projectType, isNull);
    expect(
        projectMetadata.migrateConfig
            .platformConfigs[FlutterProjectComponent.root]?.createRevision,
        'abcdefg');
    expect(
        projectMetadata.migrateConfig
            .platformConfigs[FlutterProjectComponent.root]?.baseRevision,
        'baserevision');
    expect(projectMetadata.migrateConfig.unmanagedFiles[0], 'file1');

    expect(
        logger.traceText,
        contains(
            'The value of key `version` in .metadata was expected to be YamlMap but was String'));
    expect(
        logger.traceText,
        contains(
            'The value of key `project_type` in .metadata was expected to be String but was YamlMap'));
  });

  testWithoutContext(
      'migrate config is populated when unmanaged_files is malformed', () {
    metadataFile
      ..createSync()
      ..writeAsStringSync('''
version:
  revision: b59b226a49391949247e3d6122e34bb001049ae4
  channel: stable
project_type: app

migration:
  platforms:
    - platform: root
      create_revision: abcdefg
      base_revision: baserevision

  unmanaged_files: {}
      ''');
    final FlutterProjectMetadata projectMetadata =
        FlutterProjectMetadata(metadataFile, logger);
    expect(projectMetadata.projectType, FlutterProjectType.app);
    expect(
        projectMetadata.migrateConfig
            .platformConfigs[FlutterProjectComponent.root]?.createRevision,
        'abcdefg');
    expect(
        projectMetadata.migrateConfig
            .platformConfigs[FlutterProjectComponent.root]?.baseRevision,
        'baserevision');
    // Tool uses default unamanged files list when malformed.
    expect(projectMetadata.migrateConfig.unmanagedFiles[0], 'lib/main.dart');

    expect(
        logger.traceText,
        contains(
            'The value of key `unmanaged_files` in .metadata was expected to be YamlList but was YamlMap'));
  });

  testWithoutContext('platforms is populated with a malformed entry', () {
    metadataFile
      ..createSync()
      ..writeAsStringSync('''
version:
  revision: b59b226a49391949247e3d6122e34bb001049ae4
  channel: stable
project_type: app

migration:
  platforms:
    - platform: root
      create_revision: abcdefg
      base_revision: baserevision
    - platform: android
      base_revision: baserevision
    - platform: ios
      create_revision: abcdefg
      base_revision: baserevision

  unmanaged_files:
    - 'file1'
      ''');
    final FlutterProjectMetadata projectMetadata =
        FlutterProjectMetadata(metadataFile, logger);
    expect(projectMetadata.projectType, FlutterProjectType.app);
    expect(
        projectMetadata.migrateConfig
            .platformConfigs[FlutterProjectComponent.root]?.createRevision,
        'abcdefg');
    expect(
        projectMetadata.migrateConfig
            .platformConfigs[FlutterProjectComponent.root]?.baseRevision,
        'baserevision');
    expect(
        projectMetadata.migrateConfig
            .platformConfigs[FlutterProjectComponent.ios]?.createRevision,
        'abcdefg');
    expect(
        projectMetadata.migrateConfig
            .platformConfigs[FlutterProjectComponent.ios]?.baseRevision,
        'baserevision');
    expect(
        projectMetadata.migrateConfig.platformConfigs
            .containsKey(FlutterProjectComponent.android),
        false);
    expect(projectMetadata.migrateConfig.unmanagedFiles[0], 'file1');

    expect(
        logger.traceText, contains('The key `create_revision` was not found'));
  });
}
