package rbac

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"github.com/gomodule/redigo/redis"
	"github.com/sirupsen/logrus"
	"github.rackspace.com/gorax/clients/activeDirectory"
	"github.rackspace.com/gorax/clients/eDir"
)

var (
	logCacheExpire = "redis cache expired, gathering groups for %s from AD"
	logFromCache   = "cached group info for %s found"
)

func writeRedis(ug interface{}, redisKey string) (err error) {
	r, err := redis.Dial("tcp", "redis.nsi.rackspace.com:6379", redis.DialPassword(redisKey), redis.DialConnectTimeout(time.Second*3))
	if r != nil {
		defer func() {
			if defErr := r.Close(); defErr != nil {
				logrus.Fatal(defErr)
			}
		}()
	}
	if err != nil {
		return
	}

	dat, err := json.Marshal(ug)
	if err != nil {
		return
	}
	var key string

	switch ug := ug.(type) {
	case *eDir.UserGroup:
		key = strings.ToLower(fmt.Sprintf("rbac:user#%s", ug.SSO))
		break
	case activeDirectory.UserGroup:
		key = strings.ToLower(fmt.Sprintf("rbac:user#%s", ug.SSO))
		break
	default:
		logrus.Error("unable to determine user types")
	}

	_, err = r.Do("SET", key, string(dat))
	if err != nil {
		return
	}
	_, err = r.Do("EXPIRE", key, 60)
	if err != nil {
		return
	}
	return
}

func readRedis(user, redisKey string) (s string, err error) {
	user = strings.ToLower(user)
	r, err := redis.Dial("tcp", "redis.nsi.rackspace.com:6379", redis.DialPassword(redisKey), redis.DialConnectTimeout(time.Second*3))
	if r != nil {
		defer func() {
			if defErr := r.Close(); defErr != nil {
				logrus.Fatal(defErr)
			}
		}()
	}
	if err != nil {
		logrus.Errorf("redis.Dial error %v", err)
		return
	}

	s, err = redis.String(r.Do("GET", fmt.Sprintf("rbac:user#%s", user)))
	if err != nil {
		logrus.Infof(logCacheExpire, user)
		return
	}
	logrus.Infof(logFromCache, user)
	return
}
