package org.popkit.leap.elpa.services;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.popkit.core.logger.LeapLogger;
import org.popkit.leap.elpa.entity.ArchiveVo;
import org.popkit.leap.elpa.entity.PelpaContents;
import org.popkit.leap.elpa.entity.RecipeDo;
import org.popkit.leap.elpa.entity.RecipeVo;
import org.popkit.leap.elpa.utils.PelpaUtils;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by Aborn Jiang
 * Mail aborn.jiang@gmail.com
 * 2016-05-14:15:45
 */
public class LocalCache {
    private static final long UPDATE_RECIPE_TIME = 1000*60*10; // 5 minutes
    private static Date lastUpdateTime;
    private static final ConcurrentHashMap<String, ArchiveVo> ARCHIVE = new ConcurrentHashMap<String, ArchiveVo>();
    private static final ConcurrentHashMap<String, RecipeDo> RECIPES = new ConcurrentHashMap<String, RecipeDo>();

    public static Map<String, ArchiveVo> getArchive() {
        return ARCHIVE;
    }

    public static ArchiveVo getArchive(String pkgName) {
        return ARCHIVE.get(pkgName);
    }

    public static void updateArchive(String pkgName, ArchiveVo archiveVo) {
        ARCHIVE.put(pkgName, archiveVo);
    }

    public static void updateDls(String pkgName, int dls) {
        if (RECIPES.containsKey(pkgName)) {
            RECIPES.get(pkgName).setDls(dls);
        }
    }

    public static void removeArchive(String pkgName) {
        if (ARCHIVE.containsKey(pkgName)) {
            ARCHIVE.remove(pkgName);
        }
    }

    public static void removeRecipe(String pkgName) {
        if (RECIPES.containsKey(pkgName)) {
            RECIPES.remove(pkgName);
        }
    }

    public static void writeArchiveJSON() {
        File file = new File(PelpaUtils.getHtmlPath() + PelpaContents.ARCHIVE_JSON_FILE_NAME);
        try {
            String json = LocalCache.getArchiveJSON();
            FileUtils.writeStringToFile(file, json);
        } catch (IOException e) {
            LeapLogger.warn("error writeArchiveJson", e);
        }
    }

    public static List<RecipeDo> getAllRecipeList() {
        List<RecipeDo> list = new ArrayList<RecipeDo>();
        for (String item : RECIPES.keySet()) {
            list.add(RECIPES.get(item));
        }
        return list;
    }
    /**
     * generate/update recipes.json file
     */
    public static void writeRecipesJson() {
        List<RecipeDo> list = getAllRecipeList();

        File file = new File(PelpaUtils.getHtmlPath() + PelpaContents.RECIPES_JSON_FILE_NAME);
        JSONObject jsonObject = new JSONObject();
        for (RecipeDo recipeDo : list) {
            jsonObject.put(recipeDo.getPkgName(), new RecipeVo(recipeDo));
        }

        String json = jsonObject.toString();
        try {
            FileUtils.writeStringToFile(file, json);
        } catch (IOException e) {
            //
        }
    }

    public static String getArchiveJSON() {
        JSONObject jsonObject = new JSONObject();
        if (MapUtils.isNotEmpty(ARCHIVE)) {
            for (String pkgName : ARCHIVE.keySet()) {
                jsonObject.put(pkgName, convert(ARCHIVE.get(pkgName)));
            }
        }
        return jsonObject.toJSONString();
    }

    private static ArchiveVo convert(ArchiveVo archiveVo) {
        if (StringUtils.isBlank(archiveVo.getDesc())) {
            archiveVo.setDesc(" ");
        }
        return archiveVo;
    }

    public static String getRecipesJSON() {
        JSONObject jsonObject = new JSONObject();
        if (MapUtils.isNotEmpty(RECIPES)) {
            for (String pkgName : RECIPES.keySet()) {
                jsonObject.put(pkgName, RECIPES.get(pkgName));
            }
        }
        return jsonObject.toJSONString();
    }

    public static String url(String url) {
        return url;
        //return url.replaceAll("/","\\/");
    }


    public static boolean initRecipes() {
        if (lastUpdateTime != null
                && lastUpdateTime.getTime() + UPDATE_RECIPE_TIME < new Date().getTime()) {
            return true;
        }

        if (MapUtils.isNotEmpty(RECIPES)) {
            for (String pkgName : ARCHIVE.keySet()) {
                ARCHIVE.remove(pkgName);
            }
        }

        List<RecipeDo> recipeDos = PelpaUtils.asRecipeArch(PelpaUtils.getRecipeFileList());
        if (CollectionUtils.isNotEmpty(recipeDos)) {
            for (RecipeDo recipeDo : recipeDos) {
                RECIPES.put(recipeDo.getPkgName(), recipeDo);
            }
            lastUpdateTime = new Date();
            LeapLogger.info("RECIPES updated. TimeStamp:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        }
        return true;
    }

    public static boolean updateLastCommit(String pkgName, long lastcommit) {
        if (RECIPES.containsKey(pkgName)) {
            RECIPES.get(pkgName).setLastCommit(lastcommit);
            return RECIPES.get(pkgName).getLastCommit() == lastcommit;
        } else {
            return false;
        }
    }

    public static RecipeDo getRecipeDo(String pkgName) {
        return RECIPES.get(pkgName);
    }

    public static void main(String[] args) {
        String url = "http://github.com/aaptel/preview-latex";
        String right = "http:\\/\\/github.com\\/aaptel\\/preview-latex";
        System.out.println("origin:" + url);
        System.out.println("after:" + url(url));
        System.out.println("right:" + right);
    }
}

@@ -870,24 +870,25 @@
 ocalCache %7B%0A
+%0A
     private 
@@ -941,17 +941,18 @@
 *10; // 
-5
+10
  minutes
@@ -952,16 +952,17 @@
 minutes%0A
+%0A
     priv
@@ -4333,17 +4333,17 @@
 PE_TIME 
-%3C
+%3E
  new Dat
@@ -4465,39 +4465,39 @@
 tring pkgName : 
-ARCHIVE
+RECIPES
 .keySet()) %7B%0A   
@@ -4501,39 +4501,39 @@
                 
-ARCHIVE
+RECIPES
 .remove(pkgName)
@@ -4982,26 +4982,30 @@
 .format(
-new Date()
+lastUpdateTime
 ));%0A    
@@ -5030,32 +5030,68 @@
 rn true;%0A    %7D%0A%0A
+    // TODO %E6%AF%8F%E6%AC%A1%E6%96%B0%E7%9A%84build%E5%BC%80%E5%A7%8B,%E8%A6%81%E6%B8%85%E7%A9%BAARCHIVE%0A%0A
     public stati

fix init recipes