#!/usr/bin/env python

import sys, re, mutagen, argparse, pprint, os, unicodedata
from os import listdir
from os.path import isfile, join
from mutagen.id3 import ID3

parser = argparse.ArgumentParser()
parser.add_argument('dir', help="directory of mp3 files to modify")
args = parser.parse_args()

def sortValue(data):
    articlesPattern = re.compile(ur'^(a|the|an)\s', re.UNICODE|re.IGNORECASE)
    specialsPattern = re.compile(ur'[^A-Za-z0-9\s]', re.UNICODE|re.IGNORECASE)
    spacesPattern = re.compile(ur'\s{2,}', re.UNICODE|re.IGNORECASE)
    removedArticles = articlesPattern.sub('', data);
    removedSpecials = specialsPattern.sub('', removedArticles)
    removedExtraSpaces = spacesPattern.sub(' ', removedSpecials)

    convertedValue = removedExtraSpaces.decode('utf-8').lower()

    return convertedValue

def depad(theNumber):
    pattern = re.compile(r'^0*', re.UNICODE)
    newParts = []

    parts = theNumber.decode('utf-8').split('/')

    for part in parts:
        newParts.append(pattern.sub('', part))

    newValue = u'/'.join(newParts)

    return newValue

def slugify(theString):
    value = unicodedata.normalize('NFKC', theString)
    value = re.sub(r'[^\w\s-]', '_', value).strip()
    if len(value) < 50:
        value = value[:50]

    return value


onlyfiles = [f for f in listdir(args.dir) if isfile(join(args.dir, f))]

pattern = re.compile("^.*\.mp3$", re.IGNORECASE)

for mp3file in onlyfiles:
    path = args.dir + '/' + mp3file
    match = pattern.match(path)
    if match:
        audio = mutagen.File(path)

        # Title
        audio.tags.add(mutagen.id3.TSOT(encoding=3, text=sortValue(audio['TIT2'].text[0])))
        # Album
        audio.tags.add(mutagen.id3.TSOA(encoding=3, text=sortValue(audio['TALB'].text[0])))
        # Artist
        validatedTPE1 = audio.tags.getall('TXXX:validated:TPE1')

        if not validatedTPE1:
            audio.tags.add(mutagen.id3.TSOP(encoding=3, text=sortValue(audio['TPE1'].text[0])))
        # Album Artist
        validatedTPE2 = audio.tags.getall('TXXX:validated:TPE2')

        if not validatedTPE2:
            audio.tags.add(mutagen.id3.TSO2(encoding=3, text=sortValue(audio['TPE2'].text[0])))
        # Track Data
        audio.tags.add(mutagen.id3.TRCK(encoding=3, text=depad(audio['TRCK'].text[0])))
        # Set Data
        audio.tags.add(mutagen.id3.TPOS(encoding=3, text=depad(audio['TPOS'].text[0])))

        audio.save()

        # rename file

        discInfo = audio.tags.getall('TPOS')[0].text[0].split('/')
        discNumber = discInfo[0]
        discCount = discInfo[1]

        trackInfo = audio.tags.getall('TRCK')[0].text[0].split('/')
        trackNumber = trackInfo[0].zfill(2)

        trackName = audio.tags.getall('TIT2')[0].text[0]
        cleanedTrackName = slugify(trackName)

        filename = trackNumber + ' ' + cleanedTrackName + '.mp3'

        if discCount != '1':
            filename = discNumber + '-' + filename

        # print filename
        os.rename(path, args.dir + '/' + filename)

