"use strict";
/**
 * Enhanced Feature Flags Generator
 *
 * Generates comprehensive feature flag configuration including:
 * - Multi-provider support (LaunchDarkly, Split, Unleash, Custom)
 * - Gradual rollout management
 * - User segment targeting
 * - Schedule-based rollouts
 * - Frontend and backend integration
 * - Type-safe flag definitions
 */
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 __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;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.EnhancedFeatureFlagsGenerator = void 0;
const path = __importStar(require("path"));
class EnhancedFeatureFlagsGenerator {
    id = 'enhanced-feature-flags';
    name = 'Enhanced Feature Flags Generator';
    description = 'Generates comprehensive feature flag configuration from enhanced schema';
    generate(context) {
        const { workflow, outputDirectory } = context;
        const files = [];
        if (!workflow.feature_flags) {
            return { files: [] };
        }
        const featureFlags = workflow.feature_flags;
        // Find frontend and backend components
        const frontendComponent = Object.entries(workflow.stack).find(([_, c]) => c.type === 'frontend');
        const backendComponent = Object.entries(workflow.stack).find(([_, c]) => c.type === 'backend');
        // Generate provider-specific configuration
        files.push(...this.generateProviderConfig(featureFlags, outputDirectory, backendComponent?.[0]));
        // Generate frontend feature flags integration
        if (frontendComponent) {
            const [componentName] = frontendComponent;
            files.push(...this.generateFrontendIntegration(componentName, featureFlags, outputDirectory));
        }
        // Generate backend feature flags integration
        if (backendComponent) {
            const [componentName] = backendComponent;
            files.push(...this.generateBackendIntegration(componentName, featureFlags, outputDirectory));
        }
        // Generate flag definitions and types
        files.push(...this.generateFlagDefinitions(featureFlags, outputDirectory, frontendComponent?.[0]));
        // Generate rollout management utilities
        if (this.hasRolloutFeatures(featureFlags)) {
            files.push(...this.generateRolloutUtils(featureFlags, outputDirectory, backendComponent?.[0]));
        }
        return { files };
    }
    generateProviderConfig(featureFlags, outputDirectory, backendComponent) {
        const files = [];
        const baseDir = backendComponent
            ? path.join(outputDirectory, backendComponent)
            : outputDirectory;
        files.push({
            path: path.join(baseDir, 'src/config/feature-flags.ts'),
            content: this.generateProviderConfigContent(featureFlags),
        });
        return files;
    }
    generateFrontendIntegration(componentName, featureFlags, outputDirectory) {
        const files = [];
        // Generate feature flag hook
        files.push({
            path: path.join(outputDirectory, componentName, 'src/hooks/useFeatureFlag.ts'),
            content: this.generateFeatureFlagHook(featureFlags),
        });
        // Generate feature flag provider component
        files.push({
            path: path.join(outputDirectory, componentName, 'src/providers/FeatureFlagProvider.tsx'),
            content: this.generateFeatureFlagProvider(featureFlags),
        });
        // Generate feature flag component wrapper
        files.push({
            path: path.join(outputDirectory, componentName, 'src/components/FeatureFlag.tsx'),
            content: this.generateFeatureFlagComponent(featureFlags),
        });
        return files;
    }
    generateBackendIntegration(componentName, featureFlags, outputDirectory) {
        const files = [];
        // Generate backend feature flag service
        files.push({
            path: path.join(outputDirectory, componentName, 'src/services/feature-flags.ts'),
            content: this.generateBackendService(featureFlags),
        });
        // Generate feature flag middleware
        files.push({
            path: path.join(outputDirectory, componentName, 'src/middleware/feature-flags.ts'),
            content: this.generateFeatureFlagMiddleware(featureFlags),
        });
        return files;
    }
    generateFlagDefinitions(featureFlags, outputDirectory, frontendComponent) {
        const files = [];
        const baseDir = frontendComponent
            ? path.join(outputDirectory, frontendComponent)
            : outputDirectory;
        // Generate TypeScript types
        files.push({
            path: path.join(baseDir, 'src/types/feature-flags.ts'),
            content: this.generateFlagTypes(featureFlags),
        });
        // Generate flag configuration
        files.push({
            path: path.join(baseDir, 'src/config/flags.ts'),
            content: this.generateFlagsConfig(featureFlags),
        });
        return files;
    }
    generateRolloutUtils(featureFlags, outputDirectory, backendComponent) {
        const files = [];
        const baseDir = backendComponent
            ? path.join(outputDirectory, backendComponent)
            : outputDirectory;
        files.push({
            path: path.join(baseDir, 'src/utils/rollout-manager.ts'),
            content: this.generateRolloutManager(featureFlags),
        });
        return files;
    }
    generateProviderConfigContent(featureFlags) {
        const provider = featureFlags.provider;
        switch (provider) {
            case 'launchdarkly':
                return this.generateLaunchDarklyConfig(featureFlags);
            case 'split':
                return this.generateSplitConfig(featureFlags);
            case 'unleash':
                return this.generateUnleashConfig(featureFlags);
            case 'custom':
                return this.generateCustomConfig(featureFlags);
            default:
                return this.generateCustomConfig(featureFlags);
        }
    }
    generateLaunchDarklyConfig(_featureFlags) {
        return `/**
 * LaunchDarkly Feature Flags Configuration
 * Generated by Bangstack
 */

import * as LaunchDarkly from '@launchdarkly/node-server-sdk';

const sdkKey = process.env.LAUNCHDARKLY_SDK_KEY;

if (!sdkKey) {
  throw new Error('LAUNCHDARKLY_SDK_KEY environment variable is required');
}

// Initialize LaunchDarkly client
export const ldClient = LaunchDarkly.init(sdkKey, {
  offline: process.env.NODE_ENV === 'test',
});

// Wait for client initialization
export async function initializeFeatureFlags(): Promise<void> {
  await ldClient.waitForInitialization();
  console.log('✅ LaunchDarkly client initialized');
}

/**
 * Evaluate a feature flag for a user
 */
export async function evaluateFlag(
  flagKey: string,
  user: LaunchDarkly.LDUser,
  defaultValue: boolean = false
): Promise<boolean> {
  try {
    return await ldClient.variation(flagKey, user, defaultValue);
  } catch (error) {
    console.error(\`Error evaluating flag \${flagKey}:\`, error);
    return defaultValue;
  }
}

/**
 * Evaluate all flags for a user
 */
export async function evaluateAllFlags(
  user: LaunchDarkly.LDUser
): Promise<LaunchDarkly.LDFlagSet> {
  try {
    return await ldClient.allFlagsState(user);
  } catch (error) {
    console.error('Error evaluating all flags:', error);
    return {} as LaunchDarkly.LDFlagSet;
  }
}

/**
 * Track a custom event
 */
export function trackEvent(
  eventName: string,
  user: LaunchDarkly.LDUser,
  data?: any
): void {
  ldClient.track(eventName, user, data);
}

/**
 * Close the LaunchDarkly client
 */
export async function closeFeatureFlags(): Promise<void> {
  await ldClient.close();
  console.log('LaunchDarkly client closed');
}
`;
    }
    generateSplitConfig(_featureFlags) {
        return `/**
 * Split Feature Flags Configuration
 * Generated by Bangstack
 */

import { SplitFactory } from '@splitsoftware/splitio';

const authorizationKey = process.env.SPLIT_API_KEY;

if (!authorizationKey) {
  throw new Error('SPLIT_API_KEY environment variable is required');
}

// Initialize Split SDK
const factory = SplitFactory({
  core: {
    authorizationKey,
    key: 'server',
  },
  startup: {
    readyTimeout: 10,
  },
});

export const splitClient = factory.client();

/**
 * Initialize Split SDK
 */
export async function initializeFeatureFlags(): Promise<void> {
  return new Promise((resolve, reject) => {
    splitClient.on(splitClient.Event.SDK_READY, () => {
      console.log('✅ Split SDK initialized');
      resolve();
    });

    splitClient.on(splitClient.Event.SDK_READY_TIMED_OUT, () => {
      reject(new Error('Split SDK initialization timed out'));
    });
  });
}

/**
 * Evaluate a feature flag
 */
export function evaluateFlag(
  flagKey: string,
  userId: string,
  attributes?: Record<string, any>,
  defaultValue: string = 'off'
): string {
  try {
    const treatment = splitClient.getTreatment(userId, flagKey, attributes);
    return treatment === 'control' ? defaultValue : treatment;
  } catch (error) {
    console.error(\`Error evaluating flag \${flagKey}:\`, error);
    return defaultValue;
  }
}

/**
 * Evaluate multiple feature flags
 */
export function evaluateFlags(
  flagKeys: string[],
  userId: string,
  attributes?: Record<string, any>
): Record<string, string> {
  try {
    return splitClient.getTreatments(userId, flagKeys, attributes);
  } catch (error) {
    console.error('Error evaluating flags:', error);
    return {};
  }
}

/**
 * Track an event
 */
export function trackEvent(
  userId: string,
  eventType: string,
  value?: number,
  properties?: Record<string, any>
): boolean {
  return splitClient.track(userId, 'user', eventType, value, properties);
}

/**
 * Destroy the Split client
 */
export async function closeFeatureFlags(): Promise<void> {
  await splitClient.destroy();
  console.log('Split client destroyed');
}
`;
    }
    generateUnleashConfig(_featureFlags) {
        return `/**
 * Unleash Feature Flags Configuration
 * Generated by Bangstack
 */

import { initialize, isEnabled, getVariant, Context } from 'unleash-client';

const url = process.env.UNLEASH_URL || 'http://localhost:4242/api';
const appName = process.env.UNLEASH_APP_NAME || 'default';
const instanceId = process.env.UNLEASH_INSTANCE_ID || 'development';
const apiToken = process.env.UNLEASH_API_TOKEN;

const unleash = initialize({
  url,
  appName,
  instanceId,
  customHeaders: apiToken ? { Authorization: apiToken } : {},
});

/**
 * Initialize Unleash client
 */
export async function initializeFeatureFlags(): Promise<void> {
  return new Promise((resolve, reject) => {
    unleash.on('ready', () => {
      console.log('✅ Unleash client initialized');
      resolve();
    });

    unleash.on('error', (error) => {
      console.error('Unleash initialization error:', error);
      reject(error);
    });

    setTimeout(() => {
      reject(new Error('Unleash initialization timed out'));
    }, 10000);
  });
}

/**
 * Evaluate a feature flag
 */
export function evaluateFlag(
  flagKey: string,
  context?: Context,
  defaultValue: boolean = false
): boolean {
  try {
    return isEnabled(flagKey, context, () => defaultValue);
  } catch (error) {
    console.error(\`Error evaluating flag \${flagKey}:\`, error);
    return defaultValue;
  }
}

/**
 * Get feature flag variant
 */
export function getFlagVariant(
  flagKey: string,
  context?: Context
): { name: string; enabled: boolean; payload?: any } {
  try {
    return getVariant(flagKey, context);
  } catch (error) {
    console.error(\`Error getting variant for \${flagKey}:\`, error);
    return { name: 'disabled', enabled: false };
  }
}

/**
 * Close the Unleash client
 */
export async function closeFeatureFlags(): Promise<void> {
  unleash.destroy();
  console.log('Unleash client destroyed');
}
`;
    }
    generateCustomConfig(_featureFlags) {
        return `/**
 * Custom Feature Flags Configuration
 * Generated by Bangstack
 */

interface FlagDefinition {
  name: string;
  enabled: boolean;
  rolloutPercentage?: number;
  targeting?: {
    userSegments?: string[];
  };
}

class CustomFeatureFlagClient {
  private flags: Map<string, FlagDefinition> = new Map();

  /**
   * Initialize feature flags from configuration
   */
  initialize(flags: FlagDefinition[]): void {
    flags.forEach(flag => {
      this.flags.set(flag.name, flag);
    });
    console.log(\`✅ Custom feature flags initialized: \${flags.length} flags\`);
  }

  /**
   * Evaluate a feature flag for a user
   */
  evaluateFlag(
    flagKey: string,
    userId: string,
    userSegments: string[] = [],
    defaultValue: boolean = false
  ): boolean {
    const flag = this.flags.get(flagKey);

    if (!flag) {
      console.warn(\`Flag \${flagKey} not found, using default: \${defaultValue}\`);
      return defaultValue;
    }

    // If flag is globally disabled
    if (!flag.enabled) {
      return false;
    }

    // Check user segment targeting
    if (flag.targeting?.userSegments) {
      const hasSegmentMatch = flag.targeting.userSegments.some(segment =>
        userSegments.includes(segment)
      );
      if (!hasSegmentMatch) {
        return false;
      }
    }

    // Check rollout percentage
    if (flag.rolloutPercentage !== undefined) {
      const hash = this.hashUserId(userId);
      const userPercentage = (hash % 100) + 1;
      return userPercentage <= flag.rolloutPercentage;
    }

    return true;
  }

  /**
   * Hash user ID for consistent rollout
   */
  private hashUserId(userId: string): number {
    let hash = 0;
    for (let i = 0; i < userId.length; i++) {
      const char = userId.charCodeAt(i);
      hash = ((hash << 5) - hash) + char;
      hash = hash & hash; // Convert to 32bit integer
    }
    return Math.abs(hash);
  }

  /**
   * Get all flags for a user
   */
  evaluateAllFlags(
    userId: string,
    userSegments: string[] = []
  ): Record<string, boolean> {
    const result: Record<string, boolean> = {};

    this.flags.forEach((flag, key) => {
      result[key] = this.evaluateFlag(key, userId, userSegments, false);
    });

    return result;
  }
}

export const featureFlagClient = new CustomFeatureFlagClient();

export async function initializeFeatureFlags(flags: FlagDefinition[]): Promise<void> {
  featureFlagClient.initialize(flags);
}

export function evaluateFlag(
  flagKey: string,
  userId: string,
  userSegments?: string[],
  defaultValue?: boolean
): boolean {
  return featureFlagClient.evaluateFlag(flagKey, userId, userSegments, defaultValue);
}

export function evaluateAllFlags(
  userId: string,
  userSegments?: string[]
): Record<string, boolean> {
  return featureFlagClient.evaluateAllFlags(userId, userSegments);
}

export async function closeFeatureFlags(): Promise<void> {
  console.log('Custom feature flag client closed');
}
`;
    }
    generateFeatureFlagHook(_featureFlags) {
        return `/**
 * Feature Flag Hook
 * Generated by Bangstack
 */

import { useContext, useCallback } from 'react';
import { FeatureFlagContext } from '../providers/FeatureFlagProvider';

export function useFeatureFlag(flagKey: string, defaultValue: boolean = false): boolean {
  const context = useContext(FeatureFlagContext);

  if (!context) {
    console.warn('useFeatureFlag must be used within FeatureFlagProvider');
    return defaultValue;
  }

  return context.flags[flagKey] ?? defaultValue;
}

export function useFeatureFlags(): Record<string, boolean> {
  const context = useContext(FeatureFlagContext);

  if (!context) {
    console.warn('useFeatureFlags must be used within FeatureFlagProvider');
    return {};
  }

  return context.flags;
}

export function useFeatureFlagVariant(flagKey: string): string | null {
  const context = useContext(FeatureFlagContext);

  if (!context) {
    console.warn('useFeatureFlagVariant must be used within FeatureFlagProvider');
    return null;
  }

  return context.variants?.[flagKey] ?? null;
}

export function useTrackFlagEvent() {
  const context = useContext(FeatureFlagContext);

  return useCallback((eventName: string, data?: any) => {
    if (context?.trackEvent) {
      context.trackEvent(eventName, data);
    }
  }, [context]);
}
`;
    }
    generateFeatureFlagProvider(_featureFlags) {
        return `/**
 * Feature Flag Provider
 * Generated by Bangstack
 */

import React, { createContext, useEffect, useState, ReactNode } from 'react';

interface FeatureFlagContextType {
  flags: Record<string, boolean>;
  variants?: Record<string, string>;
  trackEvent?: (eventName: string, data?: any) => void;
  loading: boolean;
  error: Error | null;
}

export const FeatureFlagContext = createContext<FeatureFlagContextType | null>(null);

interface FeatureFlagProviderProps {
  children: ReactNode;
  userId?: string;
  userAttributes?: Record<string, any>;
}

export const FeatureFlagProvider: React.FC<FeatureFlagProviderProps> = ({
  children,
  userId,
  userAttributes,
}) => {
  const [flags, setFlags] = useState<Record<string, boolean>>({});
  const [variants, setVariants] = useState<Record<string, string>>({});
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    // Fetch feature flags from API
    async function fetchFlags() {
      try {
        const response = await fetch('/api/feature-flags', {
          headers: {
            'Content-Type': 'application/json',
            ...(userId && { 'X-User-Id': userId }),
          },
        });

        if (!response.ok) {
          throw new Error('Failed to fetch feature flags');
        }

        const data = await response.json();
        setFlags(data.flags || {});
        setVariants(data.variants || {});
        setLoading(false);
      } catch (err) {
        console.error('Error fetching feature flags:', err);
        setError(err as Error);
        setLoading(false);
      }
    }

    fetchFlags();
  }, [userId, userAttributes]);

  const trackEvent = (eventName: string, data?: any) => {
    // Send tracking event to backend
    fetch('/api/feature-flags/track', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ eventName, userId, data }),
    }).catch(console.error);
  };

  return (
    <FeatureFlagContext.Provider
      value={{ flags, variants, trackEvent, loading, error }}
    >
      {children}
    </FeatureFlagContext.Provider>
  );
};
`;
    }
    generateFeatureFlagComponent(_featureFlags) {
        return `/**
 * Feature Flag Component
 * Generated by Bangstack
 */

import React, { ReactNode } from 'react';
import { useFeatureFlag } from '../hooks/useFeatureFlag';

interface FeatureFlagProps {
  flag: string;
  children: ReactNode;
  fallback?: ReactNode;
  invert?: boolean;
}

export const FeatureFlag: React.FC<FeatureFlagProps> = ({
  flag,
  children,
  fallback = null,
  invert = false,
}) => {
  const isEnabled = useFeatureFlag(flag, false);
  const shouldRender = invert ? !isEnabled : isEnabled;

  return <>{shouldRender ? children : fallback}</>;
};

interface FeatureVariantProps {
  flag: string;
  variants: Record<string, ReactNode>;
  fallback?: ReactNode;
}

export const FeatureVariant: React.FC<FeatureVariantProps> = ({
  flag,
  variants,
  fallback = null,
}) => {
  const variant = useFeatureFlagVariant(flag);

  if (!variant || !variants[variant]) {
    return <>{fallback}</>;
  }

  return <>{variants[variant]}</>;
};

// Import for variant hook
function useFeatureFlagVariant(flag: string): string | null {
  const { useFeatureFlagVariant } = require('../hooks/useFeatureFlag');
  return useFeatureFlagVariant(flag);
}
`;
    }
    generateBackendService(featureFlags) {
        return `/**
 * Feature Flags Service
 * Generated by Bangstack
 */

import { evaluateFlag, evaluateAllFlags } from '../config/feature-flags';

export interface User {
  id: string;
  email?: string;
  segments?: string[];
  attributes?: Record<string, any>;
}

/**
 * Check if a feature is enabled for a user
 */
export async function isFeatureEnabled(
  flagKey: string,
  user: User,
  defaultValue: boolean = false
): Promise<boolean> {
  try {
    ${this.generateEvaluateCallForProvider(featureFlags.provider)}
  } catch (error) {
    console.error(\`Error checking feature flag \${flagKey}:\`, error);
    return defaultValue;
  }
}

/**
 * Get all feature flags for a user
 */
export async function getAllFeatureFlags(user: User): Promise<Record<string, boolean>> {
  try {
    ${this.generateEvaluateAllCallForProvider(featureFlags.provider)}
  } catch (error) {
    console.error('Error fetching all feature flags:', error);
    return {};
  }
}

/**
 * Get feature flags for API response
 */
export async function getFeatureFlagsForClient(user: User): Promise<{
  flags: Record<string, boolean>;
  variants?: Record<string, string>;
}> {
  const flags = await getAllFeatureFlags(user);
  return { flags };
}
`;
    }
    generateEvaluateCallForProvider(provider) {
        switch (provider) {
            case 'launchdarkly':
                return `return await evaluateFlag(flagKey, {
      key: user.id,
      email: user.email,
      custom: user.attributes,
    }, defaultValue);`;
            case 'split':
                return `const treatment = evaluateFlag(flagKey, user.id, user.attributes, defaultValue ? 'on' : 'off');
    return treatment === 'on';`;
            case 'unleash':
                return `return evaluateFlag(flagKey, {
      userId: user.id,
      properties: user.attributes,
    }, defaultValue);`;
            default:
                return `return evaluateFlag(flagKey, user.id, user.segments, defaultValue);`;
        }
    }
    generateEvaluateAllCallForProvider(provider) {
        switch (provider) {
            case 'launchdarkly':
                return `const flagState = await evaluateAllFlags({
      key: user.id,
      email: user.email,
      custom: user.attributes,
    });
    return flagState.allValues();`;
            case 'unleash':
                return `return evaluateAllFlags(user.id, user.segments);`;
            default:
                return `return evaluateAllFlags(user.id, user.segments);`;
        }
    }
    generateFeatureFlagMiddleware(_featureFlags) {
        return `/**
 * Feature Flag Middleware
 * Generated by Bangstack
 */

import { Request, Response, NextFunction } from 'express';
import { getAllFeatureFlags } from '../services/feature-flags';

export async function featureFlagMiddleware(
  req: Request,
  res: Response,
  next: NextFunction
): Promise<void> {
  try {
    // Attach feature flags to request object
    const user = (req as any).user;

    if (user) {
      const flags = await getAllFeatureFlags(user);
      (req as any).featureFlags = flags;
    }

    next();
  } catch (error) {
    console.error('Error in feature flag middleware:', error);
    (req as any).featureFlags = {};
    next();
  }
}

/**
 * Middleware to require a specific feature flag
 */
export function requireFeatureFlag(flagKey: string) {
  return (req: Request, res: Response, next: NextFunction) => {
    const flags = (req as any).featureFlags || {};

    if (!flags[flagKey]) {
      return res.status(403).json({
        error: 'Feature not available',
        message: \`The \${flagKey} feature is not enabled for your account\`,
      });
    }

    next();
  };
}
`;
    }
    generateFlagTypes(featureFlags) {
        const flagNames = (featureFlags.flags || []).map(f => f.name);
        return `/**
 * Feature Flag Types
 * Generated by Bangstack
 */

export type FeatureFlagKey =
${flagNames.length > 0 ? flagNames.map(name => `  | '${name}'`).join('\n') : "  | string"};

export interface FeatureFlagConfig {
  key: FeatureFlagKey;
  name: string;
  description: string;
  enabled: boolean;
  rolloutPercentage?: number;
  rolloutStrategy?: 'gradual' | 'immediate';
  targeting?: {
    userSegments?: string[];
  };
}

export interface UserContext {
  id: string;
  email?: string;
  segments?: string[];
  attributes?: Record<string, any>;
}
`;
    }
    generateFlagsConfig(featureFlags) {
        const flags = featureFlags.flags || [];
        return `/**
 * Feature Flags Configuration
 * Generated by Bangstack
 */

import { FeatureFlagConfig } from '../types/feature-flags';

export const featureFlags: FeatureFlagConfig[] = [
${flags.map(flag => `  {
    key: '${flag.name}',
    name: '${flag.name}',
    description: 'Feature flag: ${flag.name}',
    enabled: ${flag.enabled},${flag.rollout_percentage !== undefined ? `\n    rolloutPercentage: ${flag.rollout_percentage},` : ''}${flag.rollout_strategy ? `\n    rolloutStrategy: '${flag.rollout_strategy}',` : ''}${flag.targeting?.user_segments ? `\n    targeting: { userSegments: ${JSON.stringify(flag.targeting.user_segments)} },` : ''}
  },`).join('\n')}
];

export function getFlagConfig(key: string): FeatureFlagConfig | undefined {
  return featureFlags.find(f => f.key === key);
}
`;
    }
    generateRolloutManager(_featureFlags) {
        return `/**
 * Rollout Manager
 * Handles gradual feature flag rollouts
 * Generated by Bangstack
 */

interface RolloutSchedule {
  date: string;
  percentage: number;
}

export class RolloutManager {
  /**
   * Calculate current rollout percentage based on schedule
   */
  getCurrentRolloutPercentage(schedule: RolloutSchedule[]): number {
    if (!schedule || schedule.length === 0) {
      return 100;
    }

    const now = new Date();
    const sortedSchedule = [...schedule].sort((a, b) =>
      new Date(a.date).getTime() - new Date(b.date).getTime()
    );

    // Find the applicable schedule entry
    for (let i = sortedSchedule.length - 1; i >= 0; i--) {
      const entry = sortedSchedule[i];
      const entryDate = new Date(entry.date);

      if (now >= entryDate) {
        return entry.percentage;
      }
    }

    // If current date is before all scheduled dates, return 0
    return 0;
  }

  /**
   * Check if user is in rollout based on percentage
   */
  isUserInRollout(userId: string, percentage: number): boolean {
    if (percentage >= 100) return true;
    if (percentage <= 0) return false;

    const hash = this.hashUserId(userId);
    const userPercentage = (hash % 100) + 1;

    return userPercentage <= percentage;
  }

  /**
   * Hash user ID for consistent rollout
   */
  private hashUserId(userId: string): number {
    let hash = 0;
    for (let i = 0; i < userId.length; i++) {
      const char = userId.charCodeAt(i);
      hash = ((hash << 5) - hash) + char;
      hash = hash & hash;
    }
    return Math.abs(hash);
  }

  /**
   * Get next scheduled rollout
   */
  getNextRollout(schedule: RolloutSchedule[]): RolloutSchedule | null {
    if (!schedule || schedule.length === 0) {
      return null;
    }

    const now = new Date();
    const futureSchedules = schedule.filter(s => new Date(s.date) > now);

    if (futureSchedules.length === 0) {
      return null;
    }

    return futureSchedules.sort((a, b) =>
      new Date(a.date).getTime() - new Date(b.date).getTime()
    )[0];
  }
}

export const rolloutManager = new RolloutManager();
`;
    }
    hasRolloutFeatures(featureFlags) {
        if (!featureFlags.flags)
            return false;
        return featureFlags.flags.some(flag => flag.rollout_percentage !== undefined ||
            flag.rollout_strategy !== undefined ||
            (flag.schedule && flag.schedule.length > 0));
    }
}
exports.EnhancedFeatureFlagsGenerator = EnhancedFeatureFlagsGenerator;
//# sourceMappingURL=enhanced-feature-flags-generator.js.map