#! /usr/bin/python
# -*- coding: utf-8 -*-

import os
import sys
import requests
import getpass
import random
import markdown2
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from datetime import datetime
from bs4 import BeautifulSoup

# Init config
reload(sys)
sys.setdefaultencoding('utf8')

# App Settings
APP_VERSION = "1.0.0"

# Model Settings
MODEL_CLASS_PREFIX = ""
MODEL_CLASS_SHUFIX = ""

# ShowDoc Settings
SHOW_DOC_ROOT_URL = ""
SHOW_DOC_PAGE_ID = -1

# ShowDoc User Info
SHOW_DOC_AUTH_USERNAME = ""
SHOW_DOC_AUTH_PASSWORD = ""
SHOW_DOC_AUTH_VCODE = ""
SHOW_DOC_COOKIES = None

# APIs
API_PAGE_INFO = "/index.php?s=/api/page/info"
API_LOGIN = "/index.php?s=/api/user/login"
API_VCODE = "/index.php?s=/api/common/verify"

def set_showdoc_url():
    print "Please input ShowDoc Path URL:",
    global SHOW_DOC_ROOT_URL
    SHOW_DOC_ROOT_URL = raw_input()

def set_model_filename():
    global MODEL_CLASS_PREFIX, MODEL_CLASS_SHUFIX
    print "Please input target model class prefix:",
    MODEL_CLASS_PREFIX = raw_input()
    print "Please input target model class shufix:",
    MODEL_CLASS_SHUFIX = raw_input()

def set_page_id():
    global SHOW_DOC_PAGE_ID
    print "Please input page id:",
    SHOW_DOC_PAGE_ID = raw_input()

def clear_user_info():
    global SHOW_DOC_AUTH_USERNAME, SHOW_DOC_AUTH_PASSWORD
    SHOW_DOC_AUTH_USERNAME = ""
    SHOW_DOC_AUTH_PASSWORD = ""

def set_user_info():
    global SHOW_DOC_AUTH_USERNAME,SHOW_DOC_AUTH_PASSWORD
    if len(SHOW_DOC_AUTH_USERNAME) < 1 or len(SHOW_DOC_AUTH_PASSWORD) < 1 :
        print "\n* Please input login info *"
        print "Please input your username:"
        SHOW_DOC_AUTH_USERNAME = raw_input()
        SHOW_DOC_AUTH_PASSWORD = getpass.getpass("Please input your password:")

def set_vcode():
    global SHOW_DOC_AUTH_VCODE
    print "Please input verify code:",
    SHOW_DOC_AUTH_VCODE = raw_input()

def confirm_setting():
    print "\n================================="
    print "Showdoc URL: " + SHOW_DOC_ROOT_URL
    print "PageID: " + SHOW_DOC_PAGE_ID
    print "Model class prefix: " + MODEL_CLASS_PREFIX
    print "Model class shufix: " + MODEL_CLASS_SHUFIX
    print "================================="
    print "Is correct? (Y/N) :",
    answer = raw_input()
    if answer == "Y" or answer == "y":
        return 1
    return 0

def do_login():
    global SHOW_DOC_COOKIES
    url = SHOW_DOC_ROOT_URL + API_LOGIN
    form = {"username" : SHOW_DOC_AUTH_USERNAME,
        "password" : SHOW_DOC_AUTH_PASSWORD,
        "v_code" : SHOW_DOC_AUTH_VCODE}
    result = requests.post(url, data=form, cookies=SHOW_DOC_COOKIES)
    loginResult = result.json()["error_code"]
    SHOW_DOC_COOKIES = result.cookies
    return loginResult

def download_vcode():
    print "<!> VerifyCode is needed."
    data = requests.post(SHOW_DOC_ROOT_URL + API_VCODE + "&rand=" + str(random.random()), cookies=SHOW_DOC_COOKIES)
    if os.path.exists("vcode.png"):
        os.remove("vcode.png")
    f = open("vcode.png","wb")
    f.write(data.content)
    f.close()
    print "VerifyCode image has downloaded, please see image -> close the image viewer -> input it."

def show_vcode():
    img = mpimg.imread("vcode.png")
    plt.imshow(img)
    plt.axis('off')
    plt.show()

def download_page(url,data):
    """获取url地址页面内容"""
    print "Load: " + url
    data = requests.post(url, data=data, cookies = SHOW_DOC_COOKIES)
    return data

def progress_string(text):
    html = markdown2.markdown(text,extras=["tables","code-friendly"])
    soup = BeautifulSoup(html, "html.parser")
    table2 = soup.find_all('table')[1].tbody
    trs = table2.find_all('tr')
    result = []
    print "========================================="
    for tr in trs:
        tds = tr.find_all('td')
        result.append((tds[0].text,tds[1].text,tds[2].text))
        print tds[0].text + "-" + tds[1].text + "-" + tds[2].text
    print "========================================="
    return result

def generate_swift_model(progressed_data):
    file_name = MODEL_CLASS_PREFIX + MODEL_CLASS_SHUFIX + ".swift"
    dt = datetime.now()
    code = "//\r\n//  Generated by showdoc2swiftmodel v" + APP_VERSION
    code += "\r\n//  https://github.com/teslia/showdoc2swiftmodel"
    code += "\r\n//\r\n//  Filename: " + file_name
    code += "\r\n//  Date: %s/%s/%s"%(dt.year,dt.month,dt.day)
    code += "\r\n//\r\n\r\nimport Foundation\r\nimport ObjectMapper\r\n"
    code += "\r\nstruct " + MODEL_CLASS_PREFIX + MODEL_CLASS_SHUFIX + ": Mappable {\r\n"
    for data in progressed_data:
        code += "\r\n    // " + data[2]
        code += "\r\n    var " + data[0] + ": "
        if data[1] == "string":
            code += "String?"
        elif data[1] == "int":
            code += "Int?"
        else:
            code += "Any?"
    code += "\r\n\r\n    init?(map: Map) {}"
    code += "\r\n\r\n    mutating func mapping(map: Map) {"
    for data in progressed_data:
        code += "\r\n        " + data[0] + " <- map[\"" + data[0] + "\"]"
    code += "\r\n    }\r\n}"
    f = open(file_name,"wb")
    f.write(code)
    f.close()

def main():
    os.system("cls")
    os.system("clear")
    print "Showdoc2swiftmode v" + APP_VERSION
    print "Author: Zmsky (i@xloli.com)\n"
    input_confirm = 0
    while input_confirm == 0:
        while len(SHOW_DOC_ROOT_URL) < 1:
            set_showdoc_url()
        set_page_id()
        set_model_filename()
        input_confirm = confirm_setting()

    login_result = -1
    while login_result != 0:
        if login_result == 10204:
            print ":( User auth failed,please check your input and try again."
            clear_user_info()
        elif login_result == 10206:
            download_vcode()
            show_vcode()
            set_vcode()
        elif login_result != -1:
            print ":( Unknown error,please check ShowDoc url or check network."
            return login_result
        set_user_info()
        login_result = do_login()

    print "^_^ Authentication Successful."
    url = SHOW_DOC_ROOT_URL + API_PAGE_INFO

    form = {"page_id": SHOW_DOC_PAGE_ID}
    data = download_page(url,form).json()["data"]["page_content"]
    progressed_data = progress_string(data)
    if len(progressed_data) > 0:
        generate_swift_model(progressed_data)
        print "^_^ Swift Model Generated."
    else:
        print "x_x Generate failed."
    return None

main()