// ignore_for_file: depend_on_referenced_packages

import 'dart:async';
import 'dart:io';

import 'package:archive/archive_io.dart';
import 'package:dart_framework/utils/path.dart';
import 'package:oto/oto/application.dart';
import 'package:oto/oto/commands/command.dart';
import 'package:oto/oto/data/command_data.dart';

class Zip extends Command {
  @override
  Future execute(DataCommand command) async {
    var data = DataZip.fromJson(getParam(command));
    try {
      var zipFilePath = Path.getNormal(data.zipFile);
      Application.log('Start Compress...');
      var parent = Directory(Path.getParent(zipFilePath)!);
      if (!parent.existsSync()) parent.createSync(recursive: true);
      var zipFile = File(zipFilePath);
      if (zipFile.existsSync()) zipFile.deleteSync();
      var tempDir = Directory(zipFilePath);
      if (!tempDir.existsSync()) {
        var encoder = ZipFileEncoder();
        encoder.create(zipFilePath);
        var list = data.zipList;
        for (var path in list) {
          path = Path.getNormal(path);
          var name = Path.getName(path);
          if (name == '*') {
            parent = Directory(Path.getParent(path)!);
            if (parent.existsSync()) {
              var list = parent.listSync();
              for (var item in list) {
                var dir = Directory(item.path);
                var file = File(item.path);
                if (dir.existsSync()) {
                  Application.log('- Compress Dir  --> ${dir.path}');
                  encoder.addDirectory(dir);
                }
                if (file.existsSync()) {
                  encoder.addFile(file);
                  Application.log('- Compress File --> ${file.path}');
                }
              }
            } else {
              Application.log('================== "$path" is not exist');
            }
          } else {
            var dir = Directory(path);
            var file = File(path);
            var added = false;
            if (dir.existsSync()) {
              Application.log('- Compress Dir  --> ${dir.path}');
              encoder.addDirectory(dir);
              added = true;
            }
            if (file.existsSync()) {
              encoder.addFile(file);
              Application.log('- Compress File --> ${file.path}');
              added = true;
            }
            if (!added) Application.log('================== "$path" is not exist');
          }
        }
        encoder.close();
        Application.log('Compress success: $zipFilePath');
      } else {
        throw Exception('"${tempDir.path}" is Directory');
      }
    } on Exception catch (e) {
      Application.log('Zip General Exception: $e');
    }

    return complete(0, command);
  }
}

void registerZipCommand() {
  Command.register(
    CommandType.Zip,
    () => Zip(),
    spec: const CommandSpec(
      type: CommandType.Zip,
      category: 'file',
      dataModel: 'DataZip',
      samplePath: 'assets/yaml/sample/07_file.yaml',
    ),
  );
}
