require('idownx')
require("xml")

function issupport(url)
    if url:match("^http://v.youku.com/v_show/id_") then return true end
    if url:match("^http://player.youku.com/player.php/sid/") then return true end
    return false
end

function GerFinalUrl(url)
    local json = require('json')
   	local result = {}
   	result['autoredir'] = false
    result['headers'] = {}
    result['headers']['Download-Type'] = '0'
    result['headers']['Transfer-Mode'] = '1'
    local page,head = idown.requesturl(url, '', idown.encode(result))
    local real = getlocation(head)
    return real
end

function ran()
    _seed = ((_seed * 211) + 30031) % 65536
    return (_seed / 65536)
end

function makepath(realid, format, index, key)
    local t1 = realid:sub(1,8)
    local t2 = string.format('%02X',index)
    local t3 = realid:sub(11)
    local temp0 = t1..t2..t3
    
    if format == 'hd2' then 
        path = "http://f.youku.com/player/getFlvPath/sid/00_00/st/flv/fileid/"..temp0.."?K="..key..'&hd=2'
    else
       path = "http://f.youku.com/player/getFlvPath/sid/00_00/st/"..format.."/fileid/"..temp0.."?K="..key
    end 
    return path
end

function annlyze_ex(id)
    local url = 'http://v.youku.com/player/getPlayList/VideoIDS/'..id
    local page = idown.requesturl(url)
    print(page)
    
    local jsonobj = idown.decode(page)
    _seed =  jsonobj.data[1].seed
    
    if jsonobj.data[1].streamfileids.mp4 then
        format = 'mp4'
        fileid =  jsonobj.data[1].streamfileids.mp4
    elseif jsonobj.data[1].streamfileids.flv then
        format = 'flv'
        fileid =  jsonobj.data[1].streamfileids.flv
    else
        return
    end
        
    print(_seed, key, length, fileid)
    local realfileid = getFileID(fileid)
    print(realfileid)
    local mergeparam = {}
    mergeparam.files = {}

    title = normalize(jsonobj.data[1].title)
    stream = jsonobj.data[1].segs[format]
    for i=1,#stream do
        realurl=makepath(realfileid, format, i-1, stream[i].k)
        print(realurl)
        local result = {}
        if #stream > 1 then 
            result['title'] = string.format("[%d/%d]",i,#stream)..title
            result['realname'] = title..'.'..i..'.mp4'
        else
            result['title'] = title
            result['realname'] = title..'.mp4'
        end
        result['realurl'] = realurl
        result['encode'] = 65001
        result.agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0'
        result.headers = {
         Range = ''
        }
        result.redown = 1
        local ret = idown.download(idown.encode(result))
        print(ret)
        if ret~=0 then return ret end
        table.insert(mergeparam.files, result)
    end
    if #mergeparam.files > 1 then 
        mergeparam.title = title
        mergeparam.realname = title..'.mp4'
        mergeparam.encode = 65001
        idown.merge(idown.encode(mergeparam))
    end
    return 200
end

function getFileIDMixString ()
    _mixed = ""
    local source = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\\:._-1234567890"
    local len = source:len()
    for i = 1,len do
        local index = math.floor(ran() * source:len())+1
        --print(index)
        char = source:sub(index,index)
        --print(char)
        _mixed = _mixed..char
        --print(_mixed)
        source = source:sub(1,index-1)..source:sub(index+1)
        --print(source)
    end
    print(_mixed)
end

function getFileID (fileid)
    getFileIDMixString()
    ids = split(fileid,"*")
    realid = ''
    for i,v in ipairs(ids) do
        --print(v)
        index = tonumber(v)
        if index then
        realid = realid.._mixed:sub(index+1,index+1)
        end
    end
    return realid
end

function analyze(url)
    local pid = "XMTMwOA=="
    local ctime = tostring(os.time())
    local auth = idown.crypt.md5(ctime.." "..pid.." MzZiYTMyNzc2NGQ1ZGEzM2M5N2ZjMGIwYjQzZjEzYmE=")
    local videoid = url:match("id_([%w=]+)") or url:match('/sid/([%w=]+)')
    print(ctime, auth, videoid)
    
    local apiurl = string.format('http://kuapi.youku.com/api_rest?method=video.getvideofile&pid=%s&ctime=%s&auth=%s&videoid=%s',pid,ctime,auth,videoid)
    print(apiurl)
    local page = idown.requesturl(apiurl)
    print(page)
    local allstream=xml.eval(page)
    print(allstream)
    local stream=allstream:find('stream', 'type', 'hd2') or allstream:find('stream', 'type', 'mp4') or allstream:find('stream', 'type', 'flvhd') or allstream:find('stream')
    print(stream)

    if stream==nil then
        return annlyze_ex(videoid)
    end
    
    local title = xml.find(allstream,'title')
    title = normalize(title[1])
    print(idown.toansi(title))
    local mergeparam = {}
    mergeparam.files = {}
    realurl=''
    for i=1,#stream do
        realurl=GerFinalUrl(stream[i].url)
        local result = {}
        if #stream > 1 then 
            result['title'] = string.format("[%d/%d]",i,#stream)..title
            result['realname'] = title..'.'..i..'.mp4'
        else
            result['title'] = title
            result['realname'] = title..'.mp4'
        end
        result['realurl'] = realurl
        result['encode'] = 65001
        local ret = idown.download(idown.encode(result))
        print(ret)
        if ret~=0 then return ret end
        table.insert(mergeparam.files, result)
    end
    if #mergeparam.files > 1 then 
        mergeparam.title = title
        mergeparam.realname = title..'.mp4'
        mergeparam.encode = 65001
        idown.merge(idown.encode(mergeparam))
    end
    return 200
end