"use strict";
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 __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.DefaultAccessRepository = void 0;
// src/modules/access/repositories/default-access.repository.ts
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const ssh_key_entity_1 = require("../entities/ssh-key.entity");
let DefaultAccessRepository = class DefaultAccessRepository {
    constructor(sshKeyRepo) {
        this.sshKeyRepo = sshKeyRepo;
    }
    async findAllKeys(tagFilters) {
        const query = this.sshKeyRepo
            .createQueryBuilder('ssh_key')
            .where('ssh_key.isActive = :isActive', { isActive: true });
        // Apply tag filters if present
        if (tagFilters && Object.keys(tagFilters).length > 0) {
            const conditions = [];
            const parameters = {};
            Object.entries(tagFilters).forEach(([key, value], index) => {
                if (Array.isArray(value)) {
                    // For array filters: find keys that have AT LEAST ONE of the values
                    // tags->'cluster-id' ?| array['val1', 'val2']
                    conditions.push(`ssh_key.tags->'${key}' ?| :array${index}`);
                    parameters[`array${index}`] = value;
                }
                else {
                    // For string filters: can match direct string OR be contained in array
                    conditions.push(`(
            ssh_key.tags->>'${key}' = :value${index}
            OR ssh_key.tags->'${key}' ? :value${index}
          )`);
                    parameters[`value${index}`] = value;
                }
            });
            if (conditions.length > 0) {
                query.andWhere(`(${conditions.join(' AND ')})`, parameters);
            }
        }
        const entities = await query.getMany();
        return entities;
    }
    async findKeyById(id) {
        const entity = await this.sshKeyRepo.findOneBy({ id });
        return entity;
    }
    async findKeyByFingerprint(fingerprint) {
        const entity = await this.sshKeyRepo.findOneBy({ fingerprint });
        return entity;
    }
    async findKeyByProviderKeyId(providerKeyId) {
        const entity = await this.sshKeyRepo
            .createQueryBuilder('ssh_key')
            .where(`ssh_key."providerKeyMappings"::text LIKE :pattern`, {
            pattern: `%"${providerKeyId}"%`,
        })
            .getOne();
        return entity;
    }
    async createKey(keyInput, keyPair, tags, autoGenerated) {
        const sshKey = this.sshKeyRepo.create({
            name: keyInput.name,
            type: keyInput.type || 'ed25519',
            publicKey: keyPair.publicKey,
            fingerprint: keyPair.fingerprint,
            keyPath: keyPair.privateKey,
            isActive: true,
            autoGenerated: autoGenerated || false,
            tags: tags || {},
            providerKeyMappings: {},
        });
        const savedEntity = await this.sshKeyRepo.save(sshKey);
        return savedEntity;
    }
    async deleteKey(id) {
        await this.sshKeyRepo.update(id, { isActive: false });
    }
    async updateKeyLastUsed(id) {
        const entity = await this.sshKeyRepo.findOneBy({ id });
        if (!entity) {
            throw new Error('SSH key not found');
        }
        entity.lastUsed = new Date();
        const updatedEntity = await this.sshKeyRepo.save(entity);
        return updatedEntity;
    }
    async updateKey(id, updates) {
        const entity = await this.sshKeyRepo.findOneBy({ id });
        if (!entity) {
            return null;
        }
        // Update only provided fields
        if (updates.tags !== undefined) {
            entity.tags = updates.tags;
        }
        if (updates.providerKeyMappings !== undefined) {
            entity.providerKeyMappings = updates.providerKeyMappings;
        }
        const updatedEntity = await this.sshKeyRepo.save(entity);
        return updatedEntity;
    }
};
exports.DefaultAccessRepository = DefaultAccessRepository;
exports.DefaultAccessRepository = DefaultAccessRepository = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectRepository)(ssh_key_entity_1.SSHKeyEntity)),
    __metadata("design:paramtypes", [typeorm_2.Repository])
], DefaultAccessRepository);
