"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateTenantNamespace = generateTenantNamespace;
exports.generateTenantSubdomain = generateTenantSubdomain;
exports.generateTenantUserId = generateTenantUserId;
exports.generateTenantGroupId = generateTenantGroupId;
exports.getTenantDataPath = getTenantDataPath;
exports.getTemplateResourceLimits = getTemplateResourceLimits;
exports.getTemplateMaxUsers = getTemplateMaxUsers;
exports.isDomainAvailable = isDomainAvailable;
exports.generateTenantConfig = generateTenantConfig;
exports.generateTenantDeploymentYAML = generateTenantDeploymentYAML;
exports.calculateTenantCosts = calculateTenantCosts;
/**
 * Generate Kubernetes namespace name for tenant
 */
function generateTenantNamespace(domain) {
    return `gt-${domain}`;
}
/**
 * Generate tenant subdomain
 */
function generateTenantSubdomain(domain) {
    return domain; // For now, subdomain matches domain
}
/**
 * Generate OS user ID for tenant isolation
 */
function generateTenantUserId(tenantId) {
    const baseUserId = 10000; // Start user IDs from 10000
    return baseUserId + tenantId;
}
/**
 * Generate OS group ID for tenant isolation
 */
function generateTenantGroupId(tenantId) {
    return generateTenantUserId(tenantId); // Use same ID for group
}
/**
 * Get tenant data directory path
 */
function getTenantDataPath(domain, baseDataDir = '/data') {
    return `${baseDataDir}/${domain}`;
}
/**
 * Get default resource limits based on template
 */
function getTemplateResourceLimits(template) {
    switch (template) {
        case 'basic':
            return {
                cpu: '500m',
                memory: '1Gi',
                storage: '5Gi'
            };
        case 'professional':
            return {
                cpu: '1000m',
                memory: '2Gi',
                storage: '20Gi'
            };
        case 'enterprise':
            return {
                cpu: '2000m',
                memory: '4Gi',
                storage: '100Gi'
            };
        default:
            return {
                cpu: '500m',
                memory: '1Gi',
                storage: '5Gi'
            };
    }
}
/**
 * Get default max users based on template
 */
function getTemplateMaxUsers(template) {
    switch (template) {
        case 'basic':
            return 10;
        case 'professional':
            return 100;
        case 'enterprise':
            return 1000;
        default:
            return 10;
    }
}
/**
 * Validate tenant domain availability (placeholder - would check database in real implementation)
 */
function isDomainAvailable(domain) {
    // In real implementation, this would check the database
    // For now, just check format
    const reservedDomains = ['admin', 'api', 'www', 'mail', 'ftp', 'localhost', 'gt2'];
    return !reservedDomains.includes(domain.toLowerCase());
}
/**
 * Generate complete tenant configuration from create request
 */
function generateTenantConfig(request, masterEncryptionKey) {
    const template = request.template || 'basic';
    const resourceLimits = request.resource_limits || getTemplateResourceLimits(template);
    const maxUsers = request.max_users || getTemplateMaxUsers(template);
    return {
        name: request.name.trim(),
        domain: request.domain.toLowerCase(),
        template,
        max_users: maxUsers,
        resource_limits: resourceLimits,
        namespace: generateTenantNamespace(request.domain),
        subdomain: generateTenantSubdomain(request.domain),
        status: 'pending'
    };
}
/**
 * Generate Kubernetes deployment YAML for tenant
 */
function generateTenantDeploymentYAML(tenant, tenantUserId) {
    return `
apiVersion: v1
kind: Namespace
metadata:
  name: ${tenant.namespace}
  labels:
    gt.tenant: ${tenant.domain}
    gt.template: ${tenant.template}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: ${tenant.domain}-isolation
  namespace: ${tenant.namespace}
spec:
  podSelector: {}
  policyTypes: ["Ingress", "Egress"]
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: gt-admin
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: gt-resource
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: ${tenant.domain}-config
  namespace: ${tenant.namespace}
data:
  TENANT_ID: "${tenant.id}"
  TENANT_DOMAIN: "${tenant.domain}"
  TENANT_NAME: "${tenant.name}"
  DATABASE_PATH: "/data/${tenant.domain}/app.db"
  CHROMA_COLLECTION: "gt2_${tenant.domain.replace(/-/g, '_')}_documents"
  REDIS_PREFIX: "gt2:${tenant.domain}:"
  MINIO_BUCKET: "gt2-${tenant.domain}-files"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ${tenant.domain}-app
  namespace: ${tenant.namespace}
  labels:
    app: ${tenant.domain}-app
    tenant: ${tenant.domain}
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ${tenant.domain}-app
  template:
    metadata:
      labels:
        app: ${tenant.domain}-app
        tenant: ${tenant.domain}
    spec:
      securityContext:
        runAsUser: ${tenantUserId}
        runAsGroup: ${tenantUserId}
        fsGroup: ${tenantUserId}
      containers:
      - name: frontend
        image: gt2/tenant-frontend:latest
        ports:
        - containerPort: 3000
          name: frontend
        env:
        - name: NEXT_PUBLIC_API_URL
          value: "http://localhost:8000"
        - name: NEXT_PUBLIC_WS_URL
          value: "ws://localhost:8000"
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "${tenant.resource_limits.cpu}"
            memory: "${tenant.resource_limits.memory}"
        volumeMounts:
        - name: tenant-data
          mountPath: /data/${tenant.domain}
      - name: backend
        image: gt2/tenant-backend:latest
        ports:
        - containerPort: 8000
          name: backend
        envFrom:
        - configMapRef:
            name: ${tenant.domain}-config
        env:
        - name: ENCRYPTION_KEY
          valueFrom:
            secretKeyRef:
              name: ${tenant.domain}-secrets
              key: encryption-key
        resources:
          requests:
            cpu: "200m"
            memory: "256Mi"
          limits:
            cpu: "${tenant.resource_limits.cpu}"
            memory: "${tenant.resource_limits.memory}"
        volumeMounts:
        - name: tenant-data
          mountPath: /data/${tenant.domain}
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 8000
          initialDelaySeconds: 5
          periodSeconds: 5
      volumes:
      - name: tenant-data
        persistentVolumeClaim:
          claimName: ${tenant.domain}-data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ${tenant.domain}-data
  namespace: ${tenant.namespace}
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: ${tenant.resource_limits.storage}
---
apiVersion: v1
kind: Secret
metadata:
  name: ${tenant.domain}-secrets
  namespace: ${tenant.namespace}
type: Opaque
data:
  encryption-key: ${Buffer.from(tenant.encryption_key || '').toString('base64')}
---
apiVersion: v1
kind: Service
metadata:
  name: ${tenant.domain}-service
  namespace: ${tenant.namespace}
spec:
  selector:
    app: ${tenant.domain}-app
  ports:
  - name: frontend
    port: 3000
    targetPort: 3000
  - name: backend
    port: 8000
    targetPort: 8000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ${tenant.domain}-ingress
  namespace: ${tenant.namespace}
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: ${tenant.subdomain}.gt2.local
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: ${tenant.domain}-service
            port:
              number: 8000
      - path: /
        pathType: Prefix
        backend:
          service:
            name: ${tenant.domain}-service
            port:
              number: 3000
  `.trim();
}
/**
 * Calculate tenant usage costs
 */
function calculateTenantCosts(cpuUsage, // CPU hours
memoryUsage, // Memory GB-hours
storageUsage, // Storage GB-hours
aiTokens // AI tokens used
) {
    // Pricing (example rates)
    const CPU_COST_PER_HOUR = 5; // 5 cents per CPU hour
    const MEMORY_COST_PER_GB_HOUR = 1; // 1 cent per GB-hour
    const STORAGE_COST_PER_GB_HOUR = 0.1; // 0.1 cents per GB-hour
    const AI_COST_PER_1K_TOKENS = 0.5; // 0.5 cents per 1K tokens
    const cpu_cost_cents = Math.round(cpuUsage * CPU_COST_PER_HOUR);
    const memory_cost_cents = Math.round(memoryUsage * MEMORY_COST_PER_GB_HOUR);
    const storage_cost_cents = Math.round(storageUsage * STORAGE_COST_PER_GB_HOUR);
    const ai_cost_cents = Math.round((aiTokens / 1000) * AI_COST_PER_1K_TOKENS);
    return {
        cpu_cost_cents,
        memory_cost_cents,
        storage_cost_cents,
        ai_cost_cents,
        total_cost_cents: cpu_cost_cents + memory_cost_cents + storage_cost_cents + ai_cost_cents
    };
}
