package name.abuchen.portfolio.util;

import java.net.URL;
import java.text.MessageFormat;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;

import de.jollyday.HolidayCalendar;
import de.jollyday.HolidayManager;
import de.jollyday.ManagerParameters;
import name.abuchen.portfolio.Messages;
import name.abuchen.portfolio.PortfolioLog;
import name.abuchen.portfolio.model.Security;

public class TradeCalendarManager
{
    private static String defaultCalendarCode = "trade-calendar-default"; //$NON-NLS-1$

    private static final Map<String, TradeCalendar> CACHE = new HashMap<>();

    static
    {
        // load default trading calendars

        Set<HolidayCalendar> calendars = EnumSet.of(HolidayCalendar.NYSE, HolidayCalendar.LONDON_METAL_EXCHANGE,
                        HolidayCalendar.DOW_JONES_STOXX);

        for (HolidayCalendar calendar : calendars)
        {
            HolidayManager tradingDayManager = HolidayManager.getInstance(ManagerParameters.create(calendar));
            String calendarCode = calendar.toString();
            CACHE.put(calendarCode, new TradeCalendar(calendar.toString(),
                            tradingDayManager.getCalendarHierarchy().getDescription(), tradingDayManager));
        }

        // load custom calendars

        Map<String, String> customCalendars = new HashMap<>();
        customCalendars.put("trade-calendar-default.xml", Messages.LabelTradeCalendarDefault); //$NON-NLS-1$
        customCalendars.put("trade-calendar-de.xml", Messages.LabelTradeCalendarGermany); //$NON-NLS-1$

        customCalendars.forEach((code, description) -> {
            URL url = TradeCalendarManager.class.getResource(code);
            HolidayManager m = HolidayManager.getInstance(ManagerParameters.create(url));
            CACHE.put(m.getCalendarHierarchy().getId(),
                            new TradeCalendar(m.getCalendarHierarchy().getId(), description, m));
        });
    }

    private TradeCalendarManager()
    {}

    public static Stream<TradeCalendar> getAvailableCalendar()
    {
        return CACHE.values().stream();
    }

    public static void setDefaultCalendarCode(String defaultCalendarCode)
    {
        if (!CACHE.containsKey(defaultCalendarCode))
        {
            PortfolioLog.warning(
                            MessageFormat.format("Attempting to set unkown calendar code: {0}", defaultCalendarCode)); //$NON-NLS-1$
            return;
        }

        TradeCalendarManager.defaultCalendarCode = defaultCalendarCode;
    }

    public static TradeCalendar getInstance(String calendarCode)
    {
        return CACHE.get(calendarCode);
    }

    public static TradeCalendar createEmpty()
    {
        String description = MessageFormat.format(Messages.LabelTradeCalendarUseDefault, getDefaultInstance().getDescription());
        return new TradeCalendar("", description, null); //$NON-NLS-1$
    }

    public static TradeCalendar getDefaultInstance()
    {
        return CACHE.get(defaultCalendarCode);
    }

    public static TradeCalendar getInstance(Security security)
    {
        TradeCalendar calendar = null;

        if (security.getCalendar() != null)
            calendar = CACHE.get(security.getCalendar());

        return calendar == null ? getDefaultInstance() : calendar;
    }
}

@@ -669,24 +669,57 @@
 tatic%0A    %7B%0A
+        try%0A        %7B%0A    %0A      
         // l
@@ -740,33 +740,41 @@
 ading calendars%0A
-%0A
+    %0A    
         Set%3CHoli
@@ -890,24 +890,28 @@
             
+    
 HolidayCalen
@@ -932,17 +932,25 @@
 STOXX);%0A
-%0A
+    %0A    
         
@@ -992,34 +992,42 @@
 endars)%0A        
-%7B%0A
+    %7B%0A    
             Holi
@@ -1129,24 +1129,28 @@
             
+ 
+   
 String calen
@@ -1176,24 +1176,28 @@
 toString();%0A
+    
             
@@ -1287,16 +1287,20 @@
         
+ 
+   
 tradingD
@@ -1371,35 +1371,47 @@
 ager));%0A        
-%7D%0A%0A
+    %7D%0A    %0A    
         // load 
@@ -1427,17 +1427,25 @@
 lendars%0A
-%0A
+    %0A    
         
@@ -1499,32 +1499,36 @@
 ap%3C%3E();%0A        
+    
 customCalendars.
@@ -1604,32 +1604,36 @@
 ; //$NON-NLS-1$%0A
+    
         customCa
@@ -1720,25 +1720,32 @@
 -NLS-1$%0A
-%0A
+    %0A   
         
 customCa
@@ -1728,32 +1728,33 @@
     %0A           
+ 
 customCalendars.
@@ -1786,16 +1786,20 @@
 n) -%3E %7B%0A
+    
         
@@ -1862,32 +1862,36 @@
 e);%0A            
+   
+ 
 HolidayManager m
@@ -1956,32 +1956,36 @@
 ));%0A            
+    
 CACHE.put(m.getC
@@ -2040,16 +2040,20 @@
         
+  
+  
 new Trad
@@ -2126,11 +2126,132 @@
     
-%7D);
+        %7D);%0A        %7D %0A        catch (Throwable t)%0A        %7B%0A            t.printStackTrace();%0A            throw t;%0A        %7D
 %0A   

improve debug in static function of TradeCalenderManager