// ../packager/packager-tool-case/src/index.ts
import { toolsFactoryRepository } from "@uipath/solutionpackager-tool-core";

// ../packager/packager-tool-case/src/case-tool-factory.ts
import {
  ProjectTypes as ProjectTypes2
} from "@uipath/solutionpackager-tool-core";

// ../packager/packager-tool-case/src/case-tool.ts
import {
  NugetConstants,
  NugetPackager,
  Path,
  ProjectTool,
  ProjectTypes,
  TemporaryStorageService,
  ToolErrorCodes,
  ToolResult
} from "@uipath/solutionpackager-tool-core";
var CaseConstants = {
  EntryPointsFileName: "entry-points.json",
  BindingsV2FileName: "bindings_v2.json"
};

class CaseTool extends ProjectTool {
  _temporaryStorage;
  constructor(fileSystem, logger) {
    super(fileSystem, logger);
    this._temporaryStorage = new TemporaryStorageService(fileSystem);
  }
  async restoreAsync(_options, _cancellationToken) {
    this.logger.info("Restore operation is not required for Case Management projects");
    return ToolResult.success();
  }
  async validateAsync(_options, _cancellationToken) {
    this.logger.info("Validate operation is not required for Case Management projects");
    return ToolResult.success();
  }
  async buildAsync(options, _cancellationToken) {
    const tempFolder = await this._temporaryStorage.getTempFolderPath();
    const localBuildFolder = Path.join(tempFolder, NugetConstants.OutputFolderName);
    const contentFolder = Path.join(localBuildFolder, NugetConstants.ContentFolderName);
    try {
      this.logger.progress("Copying files...");
      await this.copyFiles(options.projectPath, contentFolder);
      this.logger.progress("Creating operate.json file...");
      await this.createOperateFile(options, contentFolder);
      this.logger.progress("Creating package-descriptor.json file...");
      await this.createPackageDescriptor(localBuildFolder, contentFolder);
      return new ToolResult(ToolErrorCodes.Success, "done", [
        localBuildFolder
      ]);
    } catch (error) {
      const errorMessage = error instanceof Error ? error.toString() : String(error);
      this.logger.error(errorMessage);
      return ToolResult.error(ToolErrorCodes.InternalError, "An error occurred while building Case Management project files");
    }
  }
  async packAsync(options, cancellationToken) {
    const buildResult = await this.buildAsync(options, cancellationToken);
    if (!buildResult.isSuccess) {
      return buildResult;
    }
    const localBuildFolder = buildResult.packages[0];
    try {
      this.logger.progress("Creating NuGet package...");
      const nupkgFileName = `${options.package.id}.${options.package.version}.nupkg`;
      const nupkgPath = Path.join(options.outputPath, nupkgFileName);
      const packager = new NugetPackager(this.fileSystem);
      const result = await packager.packAsync(localBuildFolder, options.package, nupkgPath);
      this.logger.progress("Package created successfully");
      return new ToolResult(ToolErrorCodes.Success, "done", [
        result.outputPath
      ]);
    } catch (error) {
      const errorMessage = error instanceof Error ? error.toString() : String(error);
      this.logger.error(errorMessage);
      return ToolResult.error(ToolErrorCodes.InternalError, "An error occurred while packing Case Management project");
    }
  }
  async dispose() {
    this.logger.info("Disposing Case Management Tool");
    try {
      await this._temporaryStorage.cleanup();
    } catch {}
  }
  async copyFiles(sourcePath, contentFolder) {
    await this.fileSystem.mkdir(contentFolder);
    const files = await this.fileSystem.readdir(sourcePath);
    for (const file of files) {
      const sourceFile = Path.join(sourcePath, file);
      const stat = await this.fileSystem.stat(sourceFile);
      if (stat?.isFile()) {
        const content = await this.fileSystem.readFile(sourceFile);
        if (content) {
          const destinationFile = Path.join(contentFolder, file);
          await this.fileSystem.writeFile(destinationFile, content);
        }
      }
    }
  }
  async createOperateFile(options, contentFolder) {
    const operateJsonFilePath = Path.join(contentFolder, NugetConstants.OperateFileName);
    const exists = await this.fileSystem.exists(operateJsonFilePath);
    if (!exists) {
      await this.createOperateJsonFile(contentFolder, options.projectStorageId ?? "", operateJsonFilePath);
    }
  }
  async createOperateJsonFile(projectPath, projectId, filePath) {
    const entryPointsFilePath = Path.join(projectPath, CaseConstants.EntryPointsFileName);
    let mainPath = "";
    const entryPointsExists = await this.fileSystem.exists(entryPointsFilePath);
    if (entryPointsExists) {
      const entryPointsContent = await this.fileSystem.readFile(entryPointsFilePath);
      if (entryPointsContent) {
        try {
          const entryPointsText = new TextDecoder().decode(entryPointsContent);
          const entryPoints = JSON.parse(entryPointsText);
          mainPath = entryPoints.entryPoints?.[0]?.filePath ?? "";
        } catch {}
      }
    }
    const operateFileModel = {
      $schema: "https://cloud.uipath.com/draft/2024-12/operate",
      contentType: ProjectTypes.CaseManagement,
      projectId,
      main: mainPath,
      targetFramework: "Portable",
      runtimeOptions: {
        isAttended: false,
        requiresUserInteraction: false
      }
    };
    const operateJsonString = JSON.stringify(operateFileModel, null, 2);
    await this.fileSystem.writeFile(filePath, operateJsonString);
  }
  async createPackageDescriptor(localBuildFolder, contentFolder) {
    const descriptorFiles = {};
    descriptorFiles[NugetConstants.OperateFileName] = Path.join(NugetConstants.ContentFolderName, NugetConstants.OperateFileName);
    descriptorFiles[CaseConstants.EntryPointsFileName] = Path.join(NugetConstants.ContentFolderName, CaseConstants.EntryPointsFileName);
    descriptorFiles[NugetConstants.BindingsFileId] = Path.join(NugetConstants.ContentFolderName, CaseConstants.BindingsV2FileName);
    const contentFiles = await this.fileSystem.readdir(contentFolder);
    for (const file of contentFiles) {
      if (file.endsWith(".bpmn")) {
        descriptorFiles[file] = Path.join(NugetConstants.ContentFolderName, file);
      }
    }
    const packageDescriptorPath = Path.join(localBuildFolder, NugetConstants.ContentFolderName, NugetConstants.PackageDescriptorFileName);
    const packageDescriptorJson = JSON.stringify({
      $schema: "https://cloud.uipath.com/draft/2024-12/package-descriptor",
      files: descriptorFiles
    }, null, 2);
    await this.fileSystem.writeFile(packageDescriptorPath, packageDescriptorJson);
  }
}

// ../packager/packager-tool-case/src/case-tool-factory.ts
class CaseToolFactory {
  supportedTypes = [
    ProjectTypes2.CaseManagement
  ];
  async createAsync(logger, fileSystem) {
    return new CaseTool(fileSystem, logger);
  }
}

// ../packager/packager-tool-case/src/index.ts
toolsFactoryRepository.registerProjectToolFactory(new CaseToolFactory);
