# author : @thematrixsimulation

import logging
import os
from content_share.celery import app
from .models import Media
from mutagen.mp4 import MP4
from mutagen.mp3 import MP3
import subprocess
import PIL.Image
from pydub import AudioSegment
from decouple import config
from application_interface.telegram_alert import send_telegram_message
import shutil


log_file = os.path.join(config('logs'), 'error.log')
logging.basicConfig(filename=log_file,
                    filemode='a',
                    format='%(asctime)s %(name)s %(levelname)s %(message)s',
                    level=logging.INFO)


@app.task(bind=True)
def upload_task(self, file_ids):
    try:
        total = len(file_ids)
        for i in range(1, total+1, 1):
            try:
                self.update_state(state='PROGRESS', meta={'progress': i / total * 100})
                file = Media.objects.get(id=file_ids[i-1])
                logging.info(file)
                media_name = file.media_name
                f = file.file
                file_name = file.file_name
                extension = file.extension
                file_path = file_name + extension
                abs_path = os.path.join(config('save_path'), media_name, file_path)
                compressed_path = os.path.join(config('abs_compressed_path'), media_name)
                relative_path = os.path.join(config('compressed_path'), media_name)
                logging.info(f"[file:{file}]")
                media_type = file.media_type
                output_path = os.path.join(compressed_path, file_path)

                # create directory for compressed files
                if not os.path.exists(compressed_path):
                    os.mkdir(compressed_path)


                if media_type == 'video':
                    video = MP4(f)
                    runtime = round(video.info.length * 1000)
                    logging.info(f"[filename:{file_name}] [extension:{extension}] [filepath:{abs_path}] [output_path:{output_path}] [media_type:{media_type}] [runtime:{runtime}]")

                    # resize and compress original video file
                    ffmpeg_command = ['ffmpeg', '-i', abs_path, '-c:v', 'libx264', '-crf', '20', '-c:a', 'aac', '-strict', '-2', '-b:v', '400k', output_path]
                    subprocess.run(ffmpeg_command)
                    Media.objects.filter(id=file_ids[i-1]).update(compressed_file=os.path.join(relative_path, file_path), runtime=runtime)


                elif media_type == 'audio':
                    audio = MP3(f)
                    runtime = round(audio.info.length * 1000)
                    logging.info(f"[filename:{file_name}] [extension:{extension}] [filepath:{abs_path}] [media_type:{media_type}] [runtime:{runtime}]")

                    # compress original audio file
                    audio = AudioSegment.from_file(abs_path)
                    compressed = audio.set_frame_rate(16000)
                    compressed = compressed.set_sample_width(2)
                    compressed = compressed.set_channels(1)
                    compressed.export(os.path.join(compressed_path, file_path), format='mp3')
                    Media.objects.filter(id=file_ids[i-1]).update(compressed_file=os.path.join(relative_path, file_path), runtime=runtime)


                elif media_type == 'image':
                    runtime = 10000
                    logging.info(f"[filename:{file_name}] [extension:{extension}] [filepath:{abs_path}] [media_type:{media_type}] [runtime:{runtime}]")
                    
                    # resize and compress original image file
                    image = PIL.Image.open(abs_path)
                    image = image.resize((400, 400))#, resample=PIL.Image.LANCZOS)
                    image.save(os.path.join(compressed_path, file_path))
                    Media.objects.filter(id=file_ids[i-1]).update(compressed_file=os.path.join(relative_path, file_path), runtime=runtime)

                else:
                    pass

            except Exception as e:
                logging.info(f'failed with error {e}')

        # delete original uploads
        shutil.rmtree(os.path.join(config('save_path'), media_name))
    except Exception as e:
        logging.info(f'failed with error {e}')
        send_telegram_message(f'failed with error{e} while compressing uploaded file')
        return {'progress': 100, 'status': 'processing failed!','result':'Failed!'} 


    return {'progress': 100, 'status': 'Task Completed!', 'result': 'Completed!'} 




