import os
import sys
import requests
from dotenv import load_dotenv


config_file = 'github_dl.env'
username_key = 'GITHUB_USERNAME'
token_key    = 'GITHUB_TOKEN_GITHUB_DL_PY'

download_urls = []

if len(sys.argv) > 1:
    download_urls = sys.argv[1:]
    print(f"\nコマンドラインから {len(download_urls)} 個のURLが指定されました。")


def get_auth_credentials():
    """
    dotenv を使って認証情報を読み込む。
    1. スクリプトと同じディレクトリの 'github_dl.env' から認証情報ファイルのパスを取得。
    2. 指定されたパスの .env ファイルから認証情報を読み込む。
    """
    try:
        # 1. スクリプトのディレクトリにある設定ファイルから、認証情報ファイルのパスを読む
        script_dir = os.path.dirname(os.path.abspath(__file__))
        path_env_file = os.path.join(script_dir, config_file)
        
        if not os.path.exists(path_env_file):
            print(f"❌ 設定ファイルが見つかりません: {path_env_file}")
            return None, None

        load_dotenv(dotenv_path=path_env_file)
        account_inf_path = os.getenv('ACCOUNT_INF_PATH')

        if not account_inf_path or not os.path.exists(account_inf_path):
            print(f"❌ 認証情報ファイルへのパスが無効です: {account_inf_path}")
            return None, None

        # 2. 実際の認証情報ファイルを読み込む
        load_dotenv(dotenv_path=account_inf_path)
        username = os.getenv(username_key)
        token = os.getenv(token_key)

        if not username:
            print(f"❌ 認証情報ファイルに {username_key} が設定されていません。")
            return None, None
        if not token:
            print(f"❌ 認証情報ファイルに {token_key} が設定されていません。")
            return None, None
            
        print("✅ 認証情報を正常に読み込みました。")
        return username, token

    except Exception as e:
        print(f"❌ 認証情報の読み込み中にエラーが発生しました: {e}")
        return None, None

def convert_to_raw_url(url):
    """
    GitHubの通常URLをRawコンテンツURLに変換する。
    - /blob/ を削除
    - /refs/heads/ を削除
    - github.com を raw.githubusercontent.com に置換
    """
    if "raw.githubusercontent.com" in url:
        # 既にRaw URLの場合は、不要な部分を削除するだけ
        return url.replace("/refs/heads/", "/")

    if "github.com" in url:
        # 通常URLをRaw URLに変換
        raw_url = url.replace("github.com", "raw.githubusercontent.com")
        raw_url = raw_url.replace("/blob/", "/")
        raw_url = raw_url.replace("/refs/heads/", "/")
        return raw_url
        
    return url # GitHubのURLでない場合はそのまま返す

def download_file(url, save_path, auth):
    """
    認証情報を使ってファイルをダウンロードする関数。
    """
    print("-" * 50)
    print(f"Downloading from: {url}")
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
        }
        response = requests.get(url, auth=auth, headers=headers, timeout=20)
        response.raise_for_status()

        # 保存先ディレクトリがなければ作成
        os.makedirs(os.path.dirname(save_path), exist_ok=True)

        with open(save_path, 'wb') as f:
            f.write(response.content)
        print(f"✅ ダウンロード成功: {save_path}")

    except requests.exceptions.HTTPError as e:
        print(f"❌ ダウンロードエラー (HTTPError)")
        print(f"   URL: {e.request.url}")
        print(f"   ステータスコード: {e.response.status_code}")
        if e.response.status_code == 404:
            print("   ヒント: URLが正しいか、ファイルが存在するか、トークンにリポジトリへのアクセス権があるか確認してください。")
        elif e.response.status_code == 401:
            print("   ヒント: 認証に失敗しました。トークンが正しいか確認してください。")
        print(f"   レスポンス内容 (先頭300文字): \n{e.response.text[:300]}")
    except requests.exceptions.RequestException as e:
        print(f"❌ 通信エラー: {e}")
    except Exception as e:
        print(f"❌ 予期せぬエラー: {e}")

def main():
    # 認証情報を取得
    username, token = get_auth_credentials()
    if not username or not token:
        sys.exit(1) # 認証情報がなければ終了

    # 各URLについてダウンロード処理を実行
    for url in download_urls:
        # URLをRaw形式に変換
        raw_url = convert_to_raw_url(url)
        
        # URLから保存ファイル名を決定 (クエリパラメータを削除)
        file_name = os.path.basename(raw_url.split('?')[0])
        
        # カレントディレクトリに保存
        save_path = os.path.join(os.getcwd(), file_name)

        download_file(raw_url, save_path, (username, token))
    
    print("\n" + "="*50)
    print("すべてのダウンロード処理が完了しました。")


if __name__ == "__main__":
    main()
