#!/usr/bin/python

# Copyright 2005 Decklin Foster, licensed under the same terms as abcde.

import sys
import getopt
import musicbrainz
import musicbrainz.queries as mq

DEF_CD_DEV = '/dev/cdrom'

def get_toc_discid(mb, dev):
    mb.SetDevice(dev)
    try:
        mb.Query(mq.MBQ_GetCDTOC)
        return mb.GetResultData(mq.MBE_TOCGetCDIndexId)
    except musicbrainz.MusicBrainzError:
        print >>sys.stderr, "error: could not read TOC from disc"
        sys.exit(1)

def lookup_discid(mb, id):
    mb.QueryWithArgs(mq.MBQ_GetCDInfoFromCDIndexId, [id])

def fake_cddb(mb):
    matches = mb.GetResultInt(mq.MBE_GetNumAlbums)
    if matches == 0:
        print >>sys.stderr, "error: could not find an entry for this disc"
        sys.exit(1)
    if matches > 1:
        print >>sys.stderr, "warning: multiple matches, using first"

    mb.Select1(mq.MBS_SelectAlbum, 1)
    album = mb.GetResultData(mq.MBE_AlbumGetAlbumName)
    n = mb.GetResultInt(mq.MBE_AlbumGetNumTracks)

    artistid = mb.GetIDFromURL(mb.GetResultData(mq.MBE_AlbumGetAlbumArtistId))
    if artistid == mq.MBI_VARIOUS_ARTIST_ID:
        artist = 'Various Artists'
    else:
        try:
            artist = mb.GetResultData1(mq.MBE_AlbumGetArtistName, 1)
        except musicbrainz.MusicBrainzError:
            artist = 'Unknown Artist'

    if args:
        tracks = map(int, args)
    else:
        tracks = range(1, n+1)

    trackinfo = []
    for i in tracks:
        if artistid == mq.MBI_VARIOUS_ARTIST_ID:
            try:
                tartist = mb.GetResultData1(mq.MBE_AlbumGetArtistName, i)
            except musicbrainz.MusicBrainzError:
                tartist = 'Unknown Artist'
        else:
            tartist = None
        try:
            ttitle = mb.GetResultData1(mq.MBE_AlbumGetTrackName, i)
        except musicbrainz.MusicBrainzError:
            tartist = 'Unknown Track'
        try:
            tlength = mb.GetResultInt1(mq.MBE_AlbumGetTrackDuration, i)
        except musicbrainz.MusicBrainzError:
            tlength = 0
        trackinfo.append((tartist, ttitle, tlength))

    print "# fake CD database file generated by musicbrainz-get-tracks 0.1"
    print "#"
    print "# Track frame offsets:"

    # Assume standard pregap
    total_len = 2000
    for t in trackinfo:
        tartist, ttitle, tlength = t
        print "#       %d" % (total_len / (1000.0/75.0))
        total_len += tlength

    print "#"
    print "# Disc length: %d seconds" % (total_len / 1000)
    print "#"
    print "# Revision: 0"
    print "# Processed by: MusicBrainz"
    print "# Submitted by: MusicBrainz"
    print "DISCID=%s" % id
    print "DTITLE=%s / %s" % (artist, album)

    for i in range(0, len(trackinfo)):
        tartist, ttitle, tlength = trackinfo[i]
        if tartist:
            print "TTITLE%d=%s / %s" % (i, tartist, ttitle)
        else:
            print "TTITLE%d=%s" % (i, ttitle)

    print "EXTD="

    for i in range(0, len(trackinfo)):
        print "EXTD%d=" % i

    print "PLAYORDER="
    print "."

if __name__ == "__main__":
    shortopts = 'nd:i:'
    longopts = ['no-lookup', 'device=', 'id=']

    mb = musicbrainz.mb()
    mb.SetDepth(2)

    opts, args = getopt.getopt(sys.argv[1:], shortopts, longopts)

    id = None
    lookup = True
    if opts:
        for opt, arg in opts:
            if opt in ('--no-lookup', '-n'):
                lookup = False
            if opt in ('--device', '-d'):
                id = get_toc_discid(mb, arg)
            if opt in ('--id', '-i'):
                id = arg
    if not id:
        id = get_toc_discid(mb, DEF_CD_DEV)

    if lookup:
        lookup_discid(mb, id)
        fake_cddb(mb)
    else:
        print id
