<?

include_once("config.php");
//include_once("../lib/fly/fly3.php");

class Importer {
	var $key_map = array(
		DTITLE=>"title",
		DYEAR=>"year",
		DGENRE=>"genre",
	);
	function _secureArtist($artist)
	{
		if (!$artist)
			return null;
		$a = array(artist=>$artist);
		$rows = query("select no from artist where name=:artist", $a);
		if (count($rows) == 0) {
			$result = query("insert into artist 
				(name) values (:artist)", $a);
			$result = $result[lastInsertId];
		} else
			$result = $rows[0][no];
		return $result;
	}
	function _secureGenre($genre)
	{
		$a = array(
			name => $genre,
		);
		$rows = query("select * from genre where name=:name", $a);
		if (count($rows) == 0) {
			query("insert into genre (name) values (:name)", $a);
		}
	}
	function putAlbum($a)
	{
		//echo $a[discid];
		//$this->secureGenre($a[genre]);
		$result = query("insert into album 
				(title, year, discid, artist, disclength, genre, orgtitle)
			values
				(:title,:year, :discid, :artist, :disclength, :genre, :orgtitle) 
			on duplicate key update
				title=:title, year=:year, artist=:artist, disclength=:disclength, genre=:genre, orgtitle=:orgtitle", $a);
		$id = $result[lastInsertId];
		if ($id)
			return $id;
		if (!$id)
			$rows = query("select * from album where discid='$a[discid]'");
		return $rows[0][no];
	}
	function parseTitle($s)
	{
		$result = array(
			title=>$s,
			artist=>null,
			orgtitle=>null,
		);
		$n = @strpos($s, "/", 3);
		if ($n === false) {
			return $result;
		}
		$artist = trim(substr($s, 0, $n));
		if(!$artist)
			$artist = null;
		$title = trim(substr($s, $n+1, 9999));
		if(!$title)
			$title = $s;
		return array(
			title=>$title,
			artist=>$artist,
			orgtitle=>($title!=$s)?$s:null,
		);
	}
	
	function parseMeta($line)
	{
		//# Disc length: 2462 seconds	
		if(preg_match("/Disc length: (\d+)/", $line, $matches)) {
			//print_r($matches);
			return array(key=>disclength, val=>$matches[1]);
		}
		
		return null;
	}
	function putTrack($t)
	{
		query("insert into track 
				(albumno, title, artist, trackno, orgtitle)
			values
				(:albumno, :title, :artist, :trackno, :orgtitle)
			on duplicate key update
				artist=artist, title=:title;", $t);
	}
	function putTracks($albumno, $tracks)
	{
		$a = $tracks;
		foreach($tracks as $t) {
			//$artist = $this->secureArtist($t);
			//print_r($t);
			$t[albumno] = $albumno;
			// $t[artist] = $artist;
			try {
				$this->putTrack($t);
			} catch(Exception $e){
				if($this->isArtistError($e)) {
					$this->putArtist($t[artist]);
					$this->putTrack($t);
				} else
					throw $e;
			}
		}
	}
	function putArtist($artist)
	{
		$a = array(name=>$artist);
		query("insert into artist (name) values (:name);", $a);
		echo "\nnew artist found: $artist\n";
	}
	function putGenre($genre)
	{
		$a = array(name=>$genre);
		query("insert into genre (name) values (:name)", $a);
		echo "\nnew genre found: $genre\n";
	}
	
	function detect_encoding($string)
	{
		static $list = array('utf-8', 'euc-kr', 'windows-1251', 'iso-8859-1');
		$found = null;
		foreach ($list as $item) {
			$sample = iconv($item, $item, $string);
			if (md5($sample) == md5($string)) { 
				$found = $item;
				break;
			}
		}
		return $found;
	}

	function import($fn)
	{
		$s = file_get_contents($fn);
		//$encoding = mb_detect_encoding($s, "windows-1251,UTF-8,EUC-KR,ISO-8859-1",true);
		$encoding = $this->detect_encoding($s);
		if ($encoding == null)
			throw new Exception("unknown encoding: $fn");
		//$encoding = mb_detect_encoding($s, "auto",true);
		//echo "CHARACTOR CODE: $encoding\n";
		echo "\n\n$encoding : $fn is starting\n";
		$all = explode("\n", $s);
		$ini = array();
		$tracks = array();
		foreach($all as $line) {
			//echo $line;
			$aa = explode("=", $line);
			if (count($aa) < 2) {
				$aa = $this->parseMeta($line);
				$ini[$aa[key]] = $aa[val];
				continue;
			}
			$key = $this->key_map[$aa[0]];
			if ($key==null)
				$key = strtolower($aa[0]);
			$val = $aa[1];
			if ($encoding != "UTF-8")
				//$val = utf8_encode($val);
				$val = iconv($encoding, "utf-8", $val);
			
			if ($key == "title")
			{
				$ti = $this->parseTitle($val);
				if ($ini[title] && !$album[artist]) //title이 2번 들은 경우가 있다
					continue;
				echo "$val\n";
				$val = $ti[title];
				$ini[artist] = $ti[artist];
				$ini[orgtitle] = $ti[orgtitle];
			}			
			if (strpos($key, "ttitle") === 0 && $val) {
				//trackinfo
				//echo $val;
				$ti = $this->parseTitle($val);
				//echo"$val\n";
				//rint_r($ti);
				$track = array(
					trackno=>substr($key, 6, 9999)*1,
					title=>$ti[title],
					orgtitle=>$ti[orgtitle],
					artist=>$ti[artist],
				);
				$val = $track[title];				
				array_push($tracks, $track);
			}
			$ini[$key] = $val;
			//if($val)echo "$key $val\n";
		}		
		while(true) {
			try {			
				$no = $this->putAlbum($ini);
				break;
			}catch(Exception $e) {
				if ($this->isGenreError($e)) {
					$this->putGenre($ini[genre]);
				} else
				if ($this->isArtistError($e)) {
					$this->putArtist($ini[artist]);
				} else
					throw $e;
			}
		}
		$this->putTracks($no, $tracks);			
		echo "Album No.($no) : [ $ini[title] ] is imported\n";
	}
	function isArtistError($e){
		//print_r($e);
		//echo $e->getMessage();
		return strpos($e->getMessage(), "REFERENCES `artist`") !== false;
	}
	function isGenreError($e){
		//print_r($e);
		//echo $e->getMessage();
		return strpos($e->getMessage(), "FOREIGN KEY (`genre`)") !== false;
	}
	function importDir($dir)
	{
		$dir .= "/";
		echo "import root: $dir\n";
		$handle = opendir($dir);
		if(!$handle) {
			throw new Exception("can not read $dir ");
		}
		while (false !== ($entry = readdir($handle))) {
			if ($entry == "." || $entry == "..") {
				continue;
			}
			try {
				$this->import($dir.$entry);
			} catch(Exception $e) {
				echo "\n\n".$e->getMessage()."\n".$e->getTraceAsString()."\nimporting $dir.$entry failed\n\n";
				error_log($e->getMessage()."\n".$e->getTraceAsString(), 3, "errors.log");				
			}
			//echo "$entry\n";
		}
		closedir($handle);
	}
}

function extend_ini_file($ini, $fn)
{
	$cwd = getcwd();
	/*
	echo "<!--
	
		$fn
		$cwd
	
	-->";
	*/
	if (!file_exists($fn))
		return $ini;
	$newini = @parse_ini_file($fn);
	print_r("read ini: ".$newini);
	foreach($newini as $k=>$v)
	{
		if (is_numeric($v)) {
			//echo "$k $v";
			$ini[$k] = $v*1;
		} else {
			$ini[$k] = $v;
		}		
	}
	return $ini;
}

function main()
{
	//query("delete from genre; delete from artist; ");die();
	$dir = "./freedb/";
	$imp = new Importer();
	//$imp->import($dir."blues/020a0301");
	//$imp->import($dir."blues/30104627");
	$argv = $GLOBALS[argv];
	if ($argv[1] == "-f")
		$imp->import($argv[2]);
	else
	if ($argv[1] == "-d") {
		$imp->importDir(trim($argv[2]));//argv[2]);
	} else
		$imp->importDir($dir."blues");	
	
}

if ($argv[1] == 'clean')
	query("delete from artist; delete from album");
else
	main();

?>