package org.datacite.mds.service.impl;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.log4j.Logger;
import org.datacite.mds.domain.AllocatorOrDatacentre;
import org.datacite.mds.service.MagicAuthStringService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class MagicAuthStringServiceImpl implements MagicAuthStringService {
    Logger log4j = Logger.getLogger(MagicAuthStringServiceImpl.class);
    
    @Value("${salt.magicAuthString}") String salt;

    private String getBaseAuthString(AllocatorOrDatacentre user) {
        String baseAuthString = null;
        if (user != null) {
            baseAuthString = user.getBaseAuthString();
        }
        log4j.debug("base auth string for " + user.getSymbol() + ": " + baseAuthString);
        return baseAuthString;
    }

    private String saltAndHash(String baseAuth, Date date) {
        if (StringUtils.isEmpty(baseAuth)) {
            return null;
        }
        // DateFormat df = new SimpleDateFormat("yyyyMMdd");
        DateFormat df = new SimpleDateFormat("yyyyMMddhhmm");
        String rawAuth = baseAuth + ":" + df.format(date) + ":" + this.salt;
        String hashedAuth = DigestUtils.sha256Hex(rawAuth);
        log4j.debug("saltAndHash: " + hashedAuth + " <- "+ rawAuth);
        return hashedAuth;
    }

    public Collection<String> getValidAuthStrings(AllocatorOrDatacentre user) {
        List<String> list = new ArrayList<String>();
        Date curDate = new Date();
        // Date prevDate = DateUtils.addDays(curDate, -1);
        Date prevDate = DateUtils.addMinutes(curDate, -1);
        String baseAuthString = getBaseAuthString(user);
        if (baseAuthString != null) {
            list.add(saltAndHash(baseAuthString, curDate));
            list.add(saltAndHash(baseAuthString, prevDate));
        }
        log4j.debug("valid auth strings for " + user.getSymbol() + ": " + list);
        return list;
    }

    public String getCurrentAuthString(AllocatorOrDatacentre user) {
        return saltAndHash(getBaseAuthString(user), new Date());
    }

    public boolean isValidAuthString(AllocatorOrDatacentre user, String auth) {
        return user != null && !StringUtils.isEmpty(auth) && // 
                getValidAuthStrings(user).contains(auth);
    }
}

@@ -749,20 +749,16 @@
 class);%0A
-    
 %0A    @Va
@@ -787,16 +787,20 @@
 tring%7D%22)
+%0A   
  String 
@@ -1275,27 +1275,24 @@
    %7D%0A       
- //
  DateFormat 
@@ -1329,32 +1329,35 @@
 yMMdd%22);%0A       
+ //
  DateFormat df =
@@ -1589,16 +1589,17 @@
 + %22 %3C- %22
+ 
 + rawAut
@@ -1807,27 +1807,24 @@
 e();%0A       
- //
  Date prevDa
@@ -1859,32 +1859,35 @@
 te, -1);%0A       
+ //
  Date prevDate =

time between different magic auth strings: 1 day