#!/usr/bin/env python3
import os
import sys
import glob
import argparse

missing = []
for lib in ["pydub"]:
    try:
        __import__(lib)
    except ImportError:
        missing.append(lib)
if missing:
    print(f"Error: Missing libraries:\n{', '.join(missing)}")
    print(f"  pip install pydub PyAudio")
    print(f"  install ffmpeg from https://ffmpeg.org/download.html and add to PATH")
    print(f"    Linux: apt update; apt install ffmpeg; apt-get install python3-dev libasound-dev")
    print(f"    macOS: brew install ffmpeg portaudio")
    input("\nPress ENTER to terminate>>\n")
    sys.exit(1)

from pydub import AudioSegment


def convert_to_audio(input_path: str, format: str, output_path: str, bitrate: str, sample_rate: int | None,
                     update: int, overwrite: int) -> None:
    output_path = output_path or os.path.splitext(input_path)[0] + f".{format}"

    if not os.path.isfile(input_path):
        print(f"Error: '{input_path}' は存在しません。", file=sys.stderr)
        sys.exit(1)

    do_convert = False
    if os.path.exists(output_path):
        if overwrite:
            do_convert = True
            print(f"[{output_path}] は存在しますが、上書きします")
        elif not update:
            do_convert = False
            print(f"[{output_path}] は存在しますが、更新しません")
        else:
            input_mtime = os.path.getmtime(input_path)
            output_mtime = os.path.getmtime(output_path)
            if input_mtime > output_mtime:
                do_convert = True
                print(f"[{output_path}] は存在しますが、[{input_path}]の方が新しいので更新します")
            else:
                print(f"[{output_path}] は存在しますが、[{input_path}]の方が古いので更新しません")
    else:
        do_convert = True

    if not do_convert: return False

    try:
        # ファイル読み込み (動画ファイルも ffmpeg 経由で音声のみ読み込み可能)
        audio = AudioSegment.from_file(input_path)
    except Exception as e:
        print(f"ファイル読み込みエラー: {e}", file=sys.stderr)
#        sys.exit(1)
        return False

    if sample_rate:
        audio = audio.set_frame_rate(sample_rate)

    print(f"オーディオファイル [{output_path}] を作成中...")
    try:
        audio.export(output_path, format=format, bitrate=bitrate)
    except Exception as e:
        print(f"書き出しエラー: {e}", file=sys.stderr)
#        sys.exit(1)
        return False

    print(f"オーディオファイルを作成しました: {output_path}")
    return True


def main() -> None:
    parser = argparse.ArgumentParser(
        description="汎用的な MP3 抽出・変換プログラム"
    )
    parser.add_argument(
        "input",
        help="入力ファイルパス (音声/動画形式ファイル)"
    )
    parser.add_argument(
        "-f", "--format",
        default="mp3",
        help="出力ファイルタイプ (省略時はmp3)"
    )
    parser.add_argument(
        "-o", "--output",
        help="出力 MP3 ファイルパス (省略時は入力名から生成)"
    )
    parser.add_argument(
        "-b", "--bitrate",
        default="192k",
        help="MP3 ビットレート (例: 128k, 192k; デフォルト: 192k)"
    )
    parser.add_argument(
        "-r", "--samplerate",
        type=int,
        help="サンプリングレート (Hz, オプション)"
    )
    parser.add_argument(
        "--update",
        type = int,
        default = 0,
        help = "出力ファイルが存在している場合、元ファイルの方が新しい場合のみ変換"
    )
    parser.add_argument(
        "--overwrite",
        type = int,
        default = 0,
        help = "出力ファイルが存在していても上書き"
    )

    print()
    print("汎用的な MP3 抽出・変換プログラム")

    args = parser.parse_args()
    files = glob.glob(args.input)
    print(f"入力ファイル: {args.input}")
    print(f"  ファイル: {files}")
    print(f"出力フォーマット: {args.format}")
    print(f"出力ファイル: {args.output or '自動生成'}")
    print(f"ビットレート: {args.bitrate}")
    if args.samplerate:
        print(f"サンプリングレート: {args.samplerate} Hz")
    else:
        print("サンプリングレート: 省略")
    print(f"update: {args.update}")
    print(f"overwrite: {args.overwrite}")
    
    for f in files:
        convert_to_audio(f, args.format, args.output, args.bitrate, args.samplerate, args.update, args.overwrite)

    input("\nPress ENTER to terminate>>\n")
    
    
if __name__ == "__main__":
    main()
