package com.fabienli.dokuwiki.usecase;

import android.os.Build;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UrlConverter {
    protected String TAG = "UrlConverter";
    public static String WIKILINKURL = "http://dokuwiki/doku.php?id=";
    public static String WIKIBASEPATTERN = "(/[-~_:/a-zA-Z0-9]+)";
    public static String WIKILINKPATTERN = "href=\""+WIKIBASEPATTERN+"?/doku.php\\?id=";
    public static String WIKILINKPATTERN_NICEURL = "href=\""+WIKIBASEPATTERN+"?(/doku.php)?/";
    public static String WIKICREATEURL = "http://dokuwiki_create/?id=";
    public static String WIKIMEDIAPATTERN = "src=\""+WIKIBASEPATTERN+"?/lib/exe/fetch.php\\?";
    public static String WIKIMEDIAPATTERN_NICEURL = "src=\""+WIKIBASEPATTERN+"?/(lib/exe/fetch.php|_media)/(\\S+)\"";
    public static String WIKIMEDIALINKPATTERN_BASEREPLACE = "href=\""+WIKIBASEPATTERN+"?/lib/exe/fetch.php\\?[^\"]*media=";
    public static String WIKIMEDIALINKPATTERN = WIKIMEDIALINKPATTERN_BASEREPLACE+"(\\S+)\"";
    public static String WIKIMEDIALINKPATTERN_NICEURL_BASEREPLACE = "href=\""+WIKIBASEPATTERN+"?/(lib/exe/fetch.php|_media)/";
    public static String WIKIMEDIALINKPATTERN_NICEURL = WIKIMEDIALINKPATTERN_NICEURL_BASEREPLACE+"(\\S+)\"";
    public static String WIKIMEDIAMANAGERURL = "http://dokuwiki_media_manager/?";
    //TODO: handle link detail to media manager
    // format is: /lib/exe/detail.php?(\\S+)
    // nice url format is: /(lib/exe/detail.php|_detail)/(\\S+)
    protected String _cacheDir;
    public List<ImageRefData> _imageList;
    public List<String> _staticImageList;
    protected String _cssFile;

    public UrlConverter(String cacheDir, String cssFile){
        _cacheDir = cacheDir;
        _imageList = new ArrayList<>();
        _staticImageList = new ArrayList<>();
        _cssFile = cssFile;
    }

    public static boolean isPluginActionOnline(String url) {
        if(url.contains("do=plugin_do"))
            return true;
        return false;
    }
    public static String redirectPluginActionOnline(String url, String baseServerUrl){
        if(url.contains("do=plugin_do")){
            Log.d("redirectPluginActionOn", "Convert URL to call server: "+url);
            Log.d("redirectPluginActionOn", "Convert URL using server: "+baseServerUrl);
            return url.replace(WIKILINKURL, baseServerUrl);
        }
        return "";
    }

    public String fixVShareStrangeUrl(String htmlContent){
        String html=htmlContent;
        Log.i("VSHARE1",html);
        List<String> convertTable =  new ArrayList<String>();
        // list from: https://github.com/splitbrain/dokuwiki-plugin-vshare/blob/master/sites.conf
        convertTable.add("www.youtube-nocookie.com");
        convertTable.add("player.vimeo.com");
        convertTable.add("www.viddler.com");
        convertTable.add("www.slideshare.net");
        convertTable.add("www.dailymotion.com");
        convertTable.add("blip.tv");
        convertTable.add("www.break.com");
        convertTable.add("web.microsoftstream.com");
        convertTable.add("archive.org");
        convertTable.add("www.bitchute.com");
        convertTable.add("coub.com");
        convertTable.add("www.clipfish.de");
        convertTable.add("www.scivee.tv");
        convertTable.add("www.veoh.com");
        for(String e : convertTable) {

            Log.i("VSHARE","replace: "+"src=\"//"+e);
            html=html.replaceAll("src=\"//"+e, "src=\"https://"+e);
        }
        Log.i("VSHARE2",html);
       return html;
    }

    public String getHtmlContentConverted(String htmlContent){
        String html = fixVShareStrangeUrl(htmlContent);

        Log.d(TAG, "new html code: "+html);

        // find the list of media, to ensure they're here
        Pattern mediaPattern = Pattern.compile(WIKIMEDIAPATTERN +"(\\S+)\"");
        Matcher m = mediaPattern.matcher(html);
        while (m.find()) {
            ImageRefData imageData = new ImageRefData();
            imageData.width = 0;
            imageData.height = 0;
            imageData.id="";
            String[] args = m.group(2).split("&amp;");
            for (String v:args) {
                String[] opt = v.split("=");
                if(opt.length == 2){
                    if(opt[0].compareTo("w") == 0)
                        imageData.width = Integer.parseInt(opt[1]);
                    else if(opt[0].compareTo("h") == 0)
                        imageData.height = Integer.parseInt(opt[1]);
                    else if(opt[0].compareTo("media") == 0)
                        imageData.id = opt[1];
                }
            }
            Log.d(TAG, "Found image: "+imageData.toString());
            if(imageData.id.startsWith("http%3A%2F%2F") || imageData.id.startsWith("https%3A%2F%2F"))
            {
                String mediaUrl = imageData.id.replaceAll("%3A",":").replaceAll("%2F","/");
                html = html.replaceAll(WIKIMEDIAPATTERN + m.group(2) + "\"", "src=\"" + mediaUrl + "\"");
            }
            else {
                // id now contains <namespace:file.ext>
                imageData.imageFilePath = imageData.id.replaceAll(":", "/");
                _imageList.add(imageData);

                String localFilename = getLocalFileName(imageData.imageFilePath, imageData.width, imageData.height);
                html = html.replaceAll(WIKIMEDIAPATTERN + m.group(2) + "\"", "src=\"" + _cacheDir + "/" + localFilename + "\"");
            }
        }

        mediaPattern = Pattern.compile(WIKIMEDIAPATTERN_NICEURL);
        m = mediaPattern.matcher(html);
        while (m.find()) {
            Log.d(TAG, "Found image nice url: "+m.group(2));
            ImageRefData imageData = new ImageRefData();
            imageData.width = 0;
            imageData.height = 0;
            imageData.id = m.group(3);
            if(m.group(3).contains("?")) {
                String[] mediaargs = m.group(3).split("\\?");
                imageData.id = mediaargs[0];
                String[] args = mediaargs[1].split("&amp;");
                for (String v : args) {
                    String[] opt = v.split("=");
                    if (opt.length == 2) {
                        if (opt[0].compareTo("w") == 0)
                            imageData.width = Integer.parseInt(opt[1]);
                        else if (opt[0].compareTo("h") == 0)
                            imageData.height = Integer.parseInt(opt[1]);
                    }
                }
            }
            Log.d(TAG, "Found image nice url: "+imageData.toString());
            String replacementString = m.group().replace("?","\\?");
            if(imageData.id.startsWith("http%3A%2F%2F") || imageData.id.startsWith("https%3A%2F%2F"))
            {
                String mediaUrl = imageData.id.replaceAll("%3A",":").replaceAll("%2F","/");
                html = html.replaceAll(replacementString, "src=\"" + mediaUrl + "\"");
            }
            else {
                // id now contains <namespace:file.ext>
                imageData.imageFilePath = imageData.id.replaceAll(":", "/");
                _imageList.add(imageData);

                String localFilename = getLocalFileName(imageData.imageFilePath, imageData.width, imageData.height);
                html = html.replaceAll(replacementString , "src=\"" + _cacheDir + "/" + localFilename + "\"");
            }
        }

        // update internal links
        Pattern linkPattern = Pattern.compile(WIKIMEDIALINKPATTERN);
        m = linkPattern.matcher(html);
        while (m.find())
        {
            Log.d(TAG, "Found link: "+m.group(2));
            if(m.group(2).startsWith("http%3A%2F%2F") || m.group(2).startsWith("https%3A%2F%2F"))
            {
                String newUrl = m.group(2).replaceAll("%3A", ":").replaceAll("%2F", "/");
                html = html.replaceAll(WIKIMEDIALINKPATTERN_BASEREPLACE + m.group(2), "href=\"" + newUrl);
            }
            else
            {
                String localFilename =  m.group(2).replaceAll("%3A", ":").replaceAll(":", "/").replaceAll("%2F", "/");
                html = html.replaceAll(WIKIMEDIALINKPATTERN_BASEREPLACE + m.group(2), "href=\"file://" + _cacheDir + "/" + localFilename);
                ImageRefData imageData = new ImageRefData();
                imageData.width = 0;
                imageData.height = 0;
                imageData.id=m.group(2);
                imageData.imageFilePath = imageData.id.replaceAll(":", "/");
                _imageList.add(imageData);
                //_staticImageList.add("lib/exe/fetch.php?media=" + m.group(2)); // if logging is needed; it will fail !!!
            }
        }

        // internal links with nice URLs:
        linkPattern = Pattern.compile(WIKIMEDIALINKPATTERN_NICEURL);
        m = linkPattern.matcher(html);
        while (m.find()) {
            Log.d(TAG, "Found nice url link: "+m.group(3));
            String replacementString = m.group().replace("?","\\?");
            if(m.group(3).startsWith("http%3A%2F%2F") || m.group(3).startsWith("https%3A%2F%2F"))
            {
                String newUrl = m.group(3).replaceAll("%3A", ":").replaceAll("%2F", "/");
                html = html.replaceAll(replacementString, "href=\"" + newUrl+"\"");
            }
            else
            {
                String localFilename = m.group(3).replaceAll("%3A", ":").replaceAll(":", "/").replaceAll("%2F", "/");
                html = html.replaceAll(replacementString, "href=\"file://" + _cacheDir + "/" + localFilename+"\"");
            }

        }

        // update plugin images link
        String PLUGINIMGPATTERN = "src=\""+WIKIBASEPATTERN+"?/lib/plugins/";
        Pattern pluginDoPattern = Pattern.compile(PLUGINIMGPATTERN + "(\\S+)\"");
        m = pluginDoPattern.matcher(html);
        while(m.find())
        {
            Log.d(TAG, "Found plugin image: "+m.group(2));
            String localFilename = m.group(2).replaceAll("%3A", ":").replaceAll("%2F", "/");
            html = html.replaceAll(PLUGINIMGPATTERN + m.group(2), "src=\"" + _cacheDir + "/lib/plugins/" + localFilename + "\"");
            _staticImageList.add("lib/plugins/" + m.group(2));
        }

        html = html.replaceAll(WIKILINKPATTERN, "href=\""+WIKILINKURL);
        html = html.replaceAll(WIKILINKPATTERN_NICEURL, "href=\""+WIKILINKURL);

        html = addHeaders(html);
        return html;
    }


    public static String getLocalFileName(String localPath, int width, int height){
        if(width == 0 && height == 0)
            return localPath;
        else if(width == 0)
            return localPath + "__" +Integer.toString(height);
        else if(height == 0)
            return localPath + "_" +Integer.toString(width)+"_";
        return localPath + "_" + Integer.toString(width)+"_" + Integer.toString(height);
    }

    public static String getPageName(String url){
        String result = "";
        if(isInternalPageLink(url)) {
            result = url.replace(WIKILINKURL, "");
            if (result.contains("#")){
                result = result.substring(0, result.indexOf("#"));
            }
        }
        else if(isCreatePageLink(url)) {
            result = url.replace(WIKICREATEURL, "");
            // convert url characters
            try {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    result = URLDecoder.decode(result, StandardCharsets.UTF_8.name());
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            // replace special characters (all but a-z 0-9 A-Z - . or :) with underscore
            result = result.replaceAll("[^-a-zA-Z0-9:\\.]+","_").toLowerCase();

        }
        else if(isMediaManagerPageLink(url)){
            result = url.replace(WIKIMEDIAMANAGERURL, "");
        }
        else if(isLocalMediaLink(url)){
            Log.d("URL", url);
            result = url.replace("file://", "");
        }
        return result;
    }

    public static String getFileName(String filename){
        return filename.replaceAll("[^-a-zA-Z0-9.]+","_").toLowerCase();
    }

    public static boolean isInternalPageLink(String url){
        return url.startsWith(WIKILINKURL);
    }

    public static boolean isCreatePageLink(String url){
        return url.startsWith(WIKICREATEURL);
    }

    public static boolean isMediaManagerPageLink(String url){
        return url.startsWith(WIKIMEDIAMANAGERURL);
    }


    public static boolean isLocalMediaLink(String url){
        return url.startsWith("file://");
    }

    private String addHeaders(String html) {
        File cssFile = new File(_cacheDir, _cssFile);
        String START_HEADERS = "<html>\n<head>\n<link rel=\"stylesheet\" type=\"text/css\" href=\"" + cssFile.getAbsolutePath() +"\">\n</head>\n<body>\n";
        // style linked is not working ? trying to embed it directly in page
        try {
            FileInputStream fis = new FileInputStream(cssFile);
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            String str = new String(buffer);
            START_HEADERS = "<html>\n<head>\n<style>"+str+"</style>\n</head>\n<body>\n";
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        final String END_HEADERS = "\n</body>\n</html>";
        return START_HEADERS + html + END_HEADERS;
    }

    public class ImageRefData {
        public String id;
        public String imageFilePath;
        public int width = 0;
        public int height = 0;
        public String toString(){
            return id+ " width="+width+" height="+height;
        }
    }
}
