Not working  #!/usr/bin/env python3
"""
setup_project.py

This script automates the setup of the MM App Workflow project by creating the necessary
directory structure and configuration files.

Usage:
    python setup_project.py [--root-dir /path/to/project]

Options:
    --root-dir    Specify the root directory for the project. Defaults to the current directory.
"""

import os
import sys
import argparse
from pathlib import Path
import textwrap
import shutil

def parse_arguments():
    parser = argparse.ArgumentParser(
        description="Set up the MM App Workflow project structure and configuration files."
    )
    parser.add_argument(
        '--root-dir',
        type=str,
        default='.',
        help='Root directory for the project. Defaults to the current directory.'
    )
    parser.add_argument(
        '--force',
        action='store_true',
        help='Force setup by overwriting existing files.'
    )
    parser.add_argument(
        '--init-git',
        action='store_true',
        help='Initialize a git repository.'
    )
    return parser.parse_args()

def create_directories(root_dir: Path):
    directories = [
        root_dir / 'images',
        root_dir / 'audio',
        root_dir / 'logs'
    ]
    for directory in directories:
        try:
            directory.mkdir(parents=True, exist_ok=True)
            print(f"Created directory: {directory}")
        except Exception as e:
            print(f"Error creating directory {directory}: {e}")

def create_file(file_path: Path, content: str, force: bool = False):
    if file_path.exists() and not force:
        print(f"File already exists and --force not set: {file_path}")
        return
    try:
        with open(file_path, 'w') as f:
            f.write(content)
        print(f"Created file: {file_path}")
    except Exception as e:
        print(f"Error creating file {file_path}: {e}")

def create_config_yaml(root_dir: Path, force: bool):
    content = textwrap.dedent("""\
        # config.yaml
        styles_list:
          - Minimalist Style
          - Flat Design
          - Vintage/Retro Style
          - Bold & Vibrant
          - Photographic Style
          - Illustrative Style
          - Typography-Focused
          - Monochrome
          - Surreal/Abstract
          - Collage
          - Grunge
          - 3D Design
          - Futuristic/Techno
          - Pop Art
          - Geometric Patterns
          - Cinematic/Film Noir
          - Hand-Drawn Doodles
          - Pastel Aesthetic
          - Urban/Street Style

        animation:
          frame_duration_ms: 200
          loop: 0

        prompt:
          guidance_scale_range:
            min: 2.5
            max: 5.0
          num_inference_steps: 50
          height: 1024
          width: 1024

        tts:
          lang: en
          slow: false

        video:
          fps: 24
          resolution: [1024, 1024]
    """)
    create_file(root_dir / 'config.yaml', content, force)

def create_env_example(root_dir: Path, force: bool):
    content = textwrap.dedent("""\
        # .env.example
        # Copy this file to .env and fill in your details

        HF_API_KEY=your_huggingface_api_key_here
        ROOT_DIR=/path/to/mm_app
        LOG_LEVEL=INFO
    """)
    create_file(root_dir / '.env.example', content, force)

def create_requirements_txt(root_dir: Path, force: bool):
    content = textwrap.dedent("""\
        # requirements.txt
        requests==2.31.0
        PyYAML==6.0
        Pillow==10.0.0
        gTTS==2.2.6
        moviepy==2.0.0
        python-dotenv==1.0.0
    """)
    create_file(root_dir / 'requirements.txt', content, force)

def create_readme_md(root_dir: Path, force: bool):
    content = textwrap.dedent("""\
        # MM App Workflow

        ## Overview

        This application generates images based on user input, analyzes the generated images to create narratives, converts narratives to audio, and compiles everything into a video with a cascading logo.

        ## Features

        - **User Interaction**: Collects user inputs to define the image generation parameters.
        - **Image Generation**: Utilizes Hugging Face's Stable Diffusion API to generate images.
        - **Image Analysis**: Uses Salesforce's BLIP model for image captioning and narrative generation.
        - **Audio Generation**: Converts narratives to speech using `gTTS`.
        - **Video Compilation**: Combines images and audio into a video using `moviepy`, overlaying a cascading logo for branding.
        - **Logging**: Comprehensive logging for monitoring and debugging.

        ## Setup

        ### 1. Clone the Repository

        ```bash
        git clone https://github.com/yourusername/mm_app.git
        cd mm_app
        ```

        ### 2. Create a Virtual Environment

        It's recommended to use a virtual environment to manage dependencies.

        ```bash
        python3 -m venv venv
        source venv/bin/activate  # On Windows: venv\\Scripts\\activate
        ```

        ### 3. Install Dependencies

        ```bash
        pip install -r requirements.txt
        ```

        ### 4. Configure Environment Variables

        - Copy the `.env.example` to `.env`:

            ```bash
            cp .env.example .env
            ```

        - Open `.env` and set your Hugging Face API key and desired root directory:

            ```env
            HF_API_KEY=your_huggingface_api_key_here
            ROOT_DIR=path/to/mm_app
            LOG_LEVEL=INFO
            ```

        ### 5. Configure Settings

        - Edit `config.yaml` to adjust styles, animation parameters, prompt settings, TTS settings, and video settings as needed.

        ### 6. Prepare Assets

        - Place your base logo image (`logo.png`) in the `images/` directory. Ensure it's a high-quality image with a transparent background for best results.

        ## Usage

        Run the `complete_workflow.py` script:

        ```bash
        python complete_workflow.py
        ```

        ### Test Mode

        To run the script in test mode with auto-filled answers (useful for development and testing):

        ```bash
        python complete_workflow.py --test
        ```

        ## Workflow Steps

        1. **User Input**: Provide details about the main subject, environment, mood, and style of the desired image.
        2. **Image Generation**: The script sends the prompt to Hugging Face's Stable Diffusion API to generate an image.
        3. **Image Analysis**: Analyzes the generated image to create a descriptive narrative.
        4. **Audio Generation**: Converts the narrative into speech.
        5. **Video Compilation**: Combines the image and audio into a video, overlaying the cascading logo.
        6. **Logging**: All activities and errors are logged in `logs/app.log`.

        ## Logs

        Logs are stored in the `logs/` directory. They provide detailed information about the script's execution, which is helpful for debugging and monitoring.

        ## Error Handling

        The script includes comprehensive error handling to manage API failures, missing files, and other potential issues gracefully. Critical errors will terminate the workflow with appropriate log messages.

        ## Customization

        - **Styles**: Modify `config.yaml` under `styles_list` to add or remove available styles.
        - **Prompt Settings**: Adjust guidance scale, inference steps, image dimensions, etc., in `config.yaml`.
        - **TTS Settings**: Change the language or speech speed in `config.yaml`.
        - **Video Settings**: Modify frame rates and resolutions as needed.

        ## Contributing

        Contributions are welcome! Please fork the repository and submit pull requests for any enhancements or bug fixes.

        ## License

        [MIT License](LICENSE)
    """)
    create_file(root_dir / 'README.md', content, force)

def create_complete_workflow_py(root_dir: Path, force: bool):
    content = textwrap.dedent("""\"")
        # complete_workflow.py

        import os
        import json
        import random
        import base64
        import argparse
        import logging
        import sys
        import time
        from pathlib import Path

        import requests
        import yaml
        from PIL import Image
        from gtts import gTTS
        from moviepy.editor import ImageClip, AudioFileClip, CompositeVideoClip
        from dotenv import load_dotenv

        # -------------------- Configuration Management -------------------- #

        class Config:
            def __init__(self):
                # Load environment variables
                load_dotenv()

                # Set up logging
                self.log_level = os.getenv('LOG_LEVEL', 'INFO').upper()
                self.setup_logging()

                # Load configurations from YAML
                config_path = Path(__file__).parent / 'config.yaml'
                if not config_path.exists():
                    logging.error(f"Configuration file not found at {config_path}")
                    sys.exit(1)

                with open(config_path, 'r') as f:
                    self.config = yaml.safe_load(f)

                # Environment Variables
                self.api_key = os.getenv('HF_API_KEY')
                if not self.api_key:
                    logging.error("HF_API_KEY not found in environment variables. Please set it in the .env file.")
                    sys.exit(1)

                # Directory Paths
                self.root_dir = Path(os.getenv('ROOT_DIR', Path.home() / 'mm_app'))
                self.answers_path = self.root_dir / 'answers.json'
                self.prompt_path = self.root_dir / 'prompt.json'
                self.image_dir = self.root_dir / 'images'
                self.image_path = self.image_dir / 'output_image.png'
                self.audio_dir = self.root_dir / 'audio'
                self.narrative_path = self.audio_dir / 'narrative.txt'
                self.audio_output_path = self.audio_dir / 'output_audio.mp3'
                self.video_output_path = self.audio_dir / 'output_video.mp4'
                self.base_logo_path = self.image_dir / 'logo.png'
                self.cascading_logo_path = self.image_dir / 'cascading_logo.gif'

                # Ensure necessary directories exist
                self.ensure_directories()

            def setup_logging(self):
                log_dir = Path(__file__).parent / 'logs'
                log_dir.mkdir(parents=True, exist_ok=True)
                log_file = log_dir / 'app.log'

                logging.basicConfig(
                    level=getattr(logging, self.log_level, logging.INFO),
                    format='%(asctime)s - %(levelname)s - %(message)s',
                    handlers=[
                        logging.FileHandler(log_file),
                        logging.StreamHandler(sys.stdout)
                    ]
                )

            def ensure_directories(self):
                for directory in [self.image_dir, self.audio_dir]:
                    directory.mkdir(parents=True, exist_ok=True)

            def get_styles_list(self):
                return self.config.get('styles_list', [])

            def get_animation_params(self):
                return self.config.get('animation', {})

            def get_prompt_settings(self):
                return self.config.get('prompt', {})

            def get_tts_settings(self):
                return self.config.get('tts', {})

            def get_video_settings(self):
                return self.config.get('video', {})

        # -------------------- Logo Generation -------------------- #

        class LogoGenerator:
            def __init__(self, config: Config):
                self.base_logo_path = config.base_logo_path
                self.output_path = config.cascading_logo_path
                self.frame_duration = config.get_animation_params().get('frame_duration_ms', 200)
                self.loop = config.get_animation_params().get('loop', 0)

            def create_cascading_logo(self):
                """Create a cascading color-changing logo."""
                try:
                    if not self.base_logo_path.exists():
                        raise FileNotFoundError(f"Base logo not