#!/usr/bin/env python3
"""
MusicBrainz MCP Server
Use/UsingMusicBrainz APIProvide音乐Data库Query
"""

import json
import requests
import time
from fastmcp import FastMCP

# Create MCP server
mcp = FastMCP("MusicBrainz Music Database")

# MusicBrainz API基础URL
BASE_URL = "https://musicbrainz.org/ws/2"
USER_AGENT = "MCP-MusicBrainz/1.0 (mcp-agent)"

def make_request(endpoint, params):
    """Send request到MusicBrainz API"""
    headers = {
        "User-Agent": USER_AGENT,
        "Accept": "application/json"
    }
    
    # MusicBrainz要求Request间隔至少1秒
    time.sleep(1)
    
    try:
        response = requests.get(f"{BASE_URL}/{endpoint}", 
                              params=params, 
                              headers=headers, 
                              timeout=10)
        
        if response.status_code == 200:
            return response.json()
        else:
            return {"error": f"API调用Failed: HTTP {response.status_code}"}
    except Exception as e:
        return {"error": f"RequestFailed: {str(e)}"}

@mcp.tool()
def search_artist(query: str, limit: int = 25):
    """Search艺术家"""
    params = {
        "query": query,
        "fmt": "json",
        "limit": min(limit, 100)
    }
    
    data = make_request("artist", params)
    
    if "error" in data:
        return data
    
    artists = []
    for artist in data.get("artists", []):
        artists.append({
            "id": artist.get("id"),
            "name": artist.get("name"),
            "sort_name": artist.get("sort-name"),
            "type": artist.get("type"),
            "country": artist.get("country"),
            "life_span": artist.get("life-span", {}),
            "disambiguation": artist.get("disambiguation", ""),
            "score": artist.get("score", 0)
        })
    
    return {
        "artists": artists,
        "count": data.get("count", 0),
        "offset": data.get("offset", 0)
    }

@mcp.tool()
def search_album(query: str, limit: int = 25):
    """Search专辑"""
    params = {
        "query": query,
        "fmt": "json",
        "limit": min(limit, 100)
    }
    
    data = make_request("release-group", params)
    
    if "error" in data:
        return data
    
    albums = []
    for album in data.get("release-groups", []):
        artists = []
        for credit in album.get("artist-credit", []):
            if isinstance(credit, dict):
                artists.append(credit.get("artist", {}).get("name", ""))
        
        albums.append({
            "id": album.get("id"),
            "title": album.get("title"),
            "primary_type": album.get("primary-type"),
            "first_release_date": album.get("first-release-date"),
            "artists": artists,
            "disambiguation": album.get("disambiguation", ""),
            "score": album.get("score", 0)
        })
    
    return {
        "albums": albums,
        "count": data.get("count", 0),
        "offset": data.get("offset", 0)
    }

@mcp.tool()
def search_track(query: str, limit: int = 25):
    """Search歌曲"""
    params = {
        "query": query,
        "fmt": "json",
        "limit": min(limit, 100)
    }
    
    data = make_request("recording", params)
    
    if "error" in data:
        return data
    
    tracks = []
    for track in data.get("recordings", []):
        artists = []
        for credit in track.get("artist-credit", []):
            if isinstance(credit, dict):
                artists.append(credit.get("artist", {}).get("name", ""))
        
        releases = []
        for release in track.get("releases", [])[:3]:  # Limit前3个发行版
            releases.append({
                "title": release.get("title"),
                "date": release.get("date")
            })
        
        tracks.append({
            "id": track.get("id"),
            "title": track.get("title"),
            "length": track.get("length"),
            "artists": artists,
            "releases": releases,
            "disambiguation": track.get("disambiguation", ""),
            "score": track.get("score", 0)
        })
    
    return {
        "tracks": tracks,
        "count": data.get("count", 0),
        "offset": data.get("offset", 0)
    }

@mcp.tool()
def get_artist_details(artist_id: str):
    """Get/Fetch艺术家DetailedInfo/Information"""
    params = {
        "fmt": "json",
        "inc": "releases+release-groups+recordings+works+url-rels"
    }
    
    data = make_request(f"artist/{artist_id}", params)
    
    if "error" in data:
        return data
    
    # Handle/Process发行组
    release_groups = []
    for rg in data.get("release-groups", [])[:10]:  # Limit前10个
        release_groups.append({
            "id": rg.get("id"),
            "title": rg.get("title"),
            "type": rg.get("primary-type"),
            "first_release_date": rg.get("first-release-date")
        })
    
    # Handle/ProcessURL关系
    urls = {}
    for relation in data.get("relations", []):
        if relation.get("type") and relation.get("url"):
            urls[relation["type"]] = relation["url"]["resource"]
    
    return {
        "id": data.get("id"),
        "name": data.get("name"),
        "sort_name": data.get("sort-name"),
        "type": data.get("type"),
        "country": data.get("country"),
        "life_span": data.get("life-span", {}),
        "disambiguation": data.get("disambiguation", ""),
        "release_groups": release_groups,
        "urls": urls
    }

@mcp.tool()
def get_album_details(album_id: str):
    """Get/Fetch专辑DetailedInfo/Information"""
    params = {
        "fmt": "json",
        "inc": "artists+releases+recordings"
    }
    
    data = make_request(f"release-group/{album_id}", params)
    
    if "error" in data:
        return data
    
    # Handle/Process艺术家Info/Information
    artists = []
    for credit in data.get("artist-credit", []):
        if isinstance(credit, dict):
            artists.append({
                "id": credit.get("artist", {}).get("id"),
                "name": credit.get("artist", {}).get("name")
            })
    
    # Handle/Process发行版本
    releases = []
    for release in data.get("releases", [])[:5]:  # Limit前5个
        releases.append({
            "id": release.get("id"),
            "title": release.get("title"),
            "date": release.get("date"),
            "country": release.get("country"),
            "status": release.get("status")
        })
    
    return {
        "id": data.get("id"),
        "title": data.get("title"),
        "primary_type": data.get("primary-type"),
        "first_release_date": data.get("first-release-date"),
        "artists": artists,
        "releases": releases,
        "disambiguation": data.get("disambiguation", "")
    }

@mcp.tool()
def browse_artist_albums(artist_id: str, limit: int = 25):
    """浏览艺术家的专辑"""
    params = {
        "artist": artist_id,
        "fmt": "json",
        "limit": min(limit, 100),
        "type": "album"
    }
    
    data = make_request("release-group", params)
    
    if "error" in data:
        return data
    
    albums = []
    for album in data.get("release-groups", []):
        albums.append({
            "id": album.get("id"),
            "title": album.get("title"),
            "primary_type": album.get("primary-type"),
            "first_release_date": album.get("first-release-date"),
            "disambiguation": album.get("disambiguation", "")
        })
    
    return {
        "albums": albums,
        "count": data.get("count", 0),
        "offset": data.get("offset", 0)
    }

@mcp.tool()
def get_api_info():
    """Get/FetchMusicBrainz APIInfo/Information"""
    return {
        "service": "MusicBrainz",
        "description": "开放音乐百科全书",
        "api_version": "v2",
        "rate_limit": "每秒1次Request",
        "features": [
            "艺术家Search",
            "专辑Search", 
            "歌曲Search",
            "DetailedInfo/InformationQuery",
            "关联Data浏览"
        ],
        "data_coverage": [
            "艺术家Info/Information",
            "专辑和单曲",
            "歌曲录音",
            "发行Info/Information",
            "关联链接"
        ],
        "note": "Free开放Data库，请遵守Use/Using条款",
        "documentation": "https://musicbrainz.org/doc/MusicBrainz_API"
    }

if __name__ == "__main__":
    mcp.run() 