"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MediaService = void 0;
const common_1 = require("@nestjs/common");
const core_1 = require("@nestjs/core");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const path = __importStar(require("path"));
const default_settings_provider_service_1 = require("./settings/default-settings-provider.service");
const config_1 = require("@nestjs/config");
const crud_service_1 = require("./crud.service");
const file_1 = require("./file");
const error_messages_1 = require("../constants/error-messages");
const create_media_storage_provider_metadata_dto_1 = require("../dtos/create-media-storage-provider-metadata.dto");
const field_metadata_repository_1 = require("../repository/field-metadata.repository");
const media_storage_provider_metadata_repository_1 = require("../repository/media-storage-provider-metadata.repository");
const media_repository_1 = require("../repository/media.repository");
const model_metadata_repository_1 = require("../repository/model-metadata.repository");
const mediaStorageProviders_1 = require("./mediaStorageProviders");
let MediaService = class MediaService extends crud_service_1.CRUDService {
    constructor(configService, diskFileService, s3FileService, entityManager, repo, modelMetadataRepo, mediaStorageProviderMetadataRepo, fieldMetadataRepo, moduleRef) {
        super(entityManager, repo, 'media', 'solid-core', moduleRef);
        this.configService = configService;
        this.diskFileService = diskFileService;
        this.s3FileService = s3FileService;
        this.entityManager = entityManager;
        this.repo = repo;
        this.modelMetadataRepo = modelMetadataRepo;
        this.mediaStorageProviderMetadataRepo = mediaStorageProviderMetadataRepo;
        this.fieldMetadataRepo = fieldMetadataRepo;
        this.moduleRef = moduleRef;
    }
    async find(basicFilterDto, solidRequestContext = {}) {
        const data = await super.find(basicFilterDto, solidRequestContext);
        if (data.records) {
            for (const media of data.records) {
                const mediaStorageProvider = media.mediaStorageProviderMetadata;
                if (mediaStorageProvider?.type === create_media_storage_provider_metadata_dto_1.MediaStorageProviderType.Filesystem) {
                    media.relativeUri = await this.diskFileService.getUrl(this.getFullFilePathForDisk(media.relativeUri));
                }
                else if (mediaStorageProvider?.type === create_media_storage_provider_metadata_dto_1.MediaStorageProviderType.AwsS3) {
                    media.relativeUri = await this.s3FileService.getUrl(`${mediaStorageProvider.bucketName}:${media.relativeUri}`, { region: mediaStorageProvider.region });
                }
            }
        }
        if (data.groupRecords) {
            for (const group of data.groupRecords) {
                for (const media of group.groupData.records) {
                    const mediaStorageProvider = media.mediaStorageProviderMetadata;
                    if (mediaStorageProvider?.type === create_media_storage_provider_metadata_dto_1.MediaStorageProviderType.Filesystem) {
                        media.relativeUri = await this.diskFileService.getUrl(this.getFullFilePathForDisk(media.relativeUri));
                    }
                    else if (mediaStorageProvider?.type === create_media_storage_provider_metadata_dto_1.MediaStorageProviderType.AwsS3) {
                        media.relativeUri = await this.s3FileService.getUrl(`${mediaStorageProvider.bucketName}:${media.relativeUri}`, { region: mediaStorageProvider.region });
                    }
                }
            }
        }
        return data;
    }
    async upload(createDto, files) {
        if (!files) {
            throw new common_1.NotFoundException(error_messages_1.ERROR_MESSAGES.FILE_NOT_FOUND);
        }
        const savedMedias = [];
        for (let i = 0; i < files.length; i++) {
            createDto['fieldMetadata'] = await this.fieldMetadataRepo.findOne({
                where: {
                    id: createDto['fieldMetadataId']
                },
            });
            createDto['modelMetadata'] = await this.modelMetadataRepo.findOne({
                where: {
                    id: createDto['modelMetadataId']
                },
            });
            createDto['mediaStorageProviderMetadata'] = await this.mediaStorageProviderMetadataRepo.findOne({
                where: {
                    id: createDto['mediaStorageProviderMetadataId']
                },
            });
            const file = files[i];
            switch (createDto.mediaStorageProviderMetadata.type) {
                case create_media_storage_provider_metadata_dto_1.MediaStorageProviderType.Filesystem:
                    const fileStoragePath = this.getFullFilePathForDisk(this.getFileName(file));
                    await this.diskFileService.copy(file.path, fileStoragePath);
                    createDto['relativeUri'] = this.getFileName(file);
                    break;
                case create_media_storage_provider_metadata_dto_1.MediaStorageProviderType.AwsS3:
                    const fileName = this.getFileName(file);
                    const bucketName = createDto.mediaStorageProviderMetadata.bucketName;
                    const fileData = await this.diskFileService.read(file.path);
                    await this.s3FileService.write(`${bucketName}:${fileName}`, fileData, { contentType: file.mimetype });
                    createDto['relativeUri'] = fileName;
                    break;
                default:
                    break;
            }
            await this.diskFileService.delete(file.path);
            const media = this.repo.create(createDto);
            const savedMedia = await this.repo.save(media);
            savedMedias.push(savedMedia);
        }
        return savedMedias;
    }
    async remove(id) {
        const media = await this.repo.findOne({
            where: {
                id: id,
            },
            relations: ['mediaStorageProviderMetadata', 'fieldMetadata', 'fieldMetadata.model', 'fieldMetadata.mediaStorageProvider'],
        });
        const modelEntity = await this.modelMetadataRepo.findOne({
            where: {
                id: media.entityId,
            }
        });
        const storageProviderType = media.mediaStorageProviderMetadata.type;
        const storageProvider = await (0, mediaStorageProviders_1.getMediaStorageProvider)(this.moduleRef, storageProviderType);
        await storageProvider.delete(modelEntity, media.fieldMetadata);
        return this.repo.remove(media);
    }
    getFullFilePathForDisk(fileName) {
        const base = this.settingService.getConfigValue("fileStorageDir")
            || default_settings_provider_service_1.DEFAULT_MEDIA_FILE_STORAGE_DIR;
        if (path.isAbsolute(fileName) || fileName.startsWith(`${base}/`)) {
            return fileName;
        }
        return `${base}/${fileName}`;
    }
    getFileName(file) {
        return `${file.filename}-${file.originalname}`;
    }
};
exports.MediaService = MediaService;
exports.MediaService = MediaService = __decorate([
    (0, common_1.Injectable)(),
    __param(3, (0, typeorm_1.InjectEntityManager)()),
    __param(5, (0, common_1.Inject)((0, common_1.forwardRef)(() => model_metadata_repository_1.ModelMetadataRepository))),
    __metadata("design:paramtypes", [config_1.ConfigService,
        file_1.DiskFileService,
        file_1.S3FileService,
        typeorm_2.EntityManager,
        media_repository_1.MediaRepository,
        model_metadata_repository_1.ModelMetadataRepository,
        media_storage_provider_metadata_repository_1.MediaStorageProviderMetadataRepository,
        field_metadata_repository_1.FieldMetadataRepository,
        core_1.ModuleRef])
], MediaService);
//# sourceMappingURL=media.service.js.map