package plugin

/*
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

import (
	"fmt"
	"net/http"
	"net/url"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/apache/trafficcontrol/grove/web"

	"github.com/apache/trafficcontrol/lib/go-log"
	"github.com/apache/trafficcontrol/lib/go-rfc"

	"code.cloudfoundry.org/bytefmt"
)

func init() {
	AddPlugin(10000, Funcs{onRequest: cacheinspect})
}

// CacheStatsEndpoint is our reserved path
const CacheStatsEndpoint = "/_cacheinspect"

func writeHTMLPageHeader(w http.ResponseWriter) {
	w.Header().Set("Content-Type", "text/html")
	w.Write([]byte(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Grove Cache Inspector</title>
</head>
<body>
<pre>
`))

}

func writeHTMLPageFooter(w http.ResponseWriter) {
	w.Write([]byte(`
</pre>
</body>
</html>
`))
}

func cacheinspect(icfg interface{}, d OnRequestData) bool {
	if !strings.HasPrefix(d.R.URL.Path, CacheStatsEndpoint) {
		log.Debugf("plugin onrequest http_cacheinspect returning, not in path '" + d.R.URL.Path + "'\n")
		return false
	}

	log.Debugf("plugin onrequest http_cacheinspect calling\n")

	reqTime := time.Now()
	w := d.W
	req := d.R

	// TODO access log? Stats byte count?
	ip, err := web.GetIP(req)
	if err != nil {
		code := http.StatusInternalServerError
		w.WriteHeader(code)
		w.Write([]byte(http.StatusText(code)))
		log.Errorln("statHandler ServeHTTP failed to get IP: " + ip.String())
		return true
	}
	if !d.StatRules.Allowed(ip) {
		code := http.StatusForbidden
		w.WriteHeader(code)
		w.Write([]byte(http.StatusText(code)))
		log.Debugln("statHandler.ServeHTTP IP " + ip.String() + " FORBIDDEN") // TODO event?
		return true
	}

	respCode := http.StatusOK
	w.WriteHeader(respCode)
	writeHTMLPageHeader(w)
	qstringOptions := req.URL.Query()

	// The default cache = "", which is the default memcache
	cacheToDisplay := ""
	showSelectCache := false
	if cNameArr, cNamePresent := qstringOptions["cache"]; cNamePresent {
		showSelectCache = true
		cacheToDisplay = cNameArr[0]
	}
	if keyArr, showKey := qstringOptions["key"]; showKey {
		hLine := fmt.Sprintf("Key: %s cache: \"%s\"\n\n", keyArr[0], cacheToDisplay)
		w.Write([]byte(hLine))
		if cacheObject, ok := d.Stats.CachePeek(keyArr[0], cacheToDisplay); ok {
			for k, v := range cacheObject.ReqHeaders {
				w.Write([]byte(fmt.Sprintf("  > %s: %s\n", k, strings.Join(v, ","))))
			}
			w.Write([]byte("\n"))
			for k, v := range cacheObject.RespHeaders {
				w.Write([]byte(fmt.Sprintf("  < %s: %s\n", k, strings.Join(v, ","))))
			}
			w.Write([]byte("\n"))
			w.Write([]byte(fmt.Sprintf("  Code:                         %d\n", cacheObject.Code)))
			w.Write([]byte(fmt.Sprintf("  OriginCode:                   %d\n", cacheObject.OriginCode)))
			w.Write([]byte(fmt.Sprintf("  ProxyURL:                     %s\n", cacheObject.ProxyURL)))
			w.Write([]byte(fmt.Sprintf("  ReqTime:                      %v\n", cacheObject.ReqTime)))
			w.Write([]byte(fmt.Sprintf("  ReqRespTime:                  %v\n", cacheObject.ReqRespTime)))
			w.Write([]byte(fmt.Sprintf("  RespRespTime:                 %v\n", cacheObject.RespRespTime)))
			w.Write([]byte(fmt.Sprintf("  LastModified:                 %v\n", cacheObject.LastModified)))
			w.Write([]byte(fmt.Sprintf("  HitCount:                     %v\n", cacheObject.HitCount)))
		} else {
			w.Write([]byte("Not Found"))
		}
	} else {
		searchArr, doSearch := qstringOptions["search"]
		cacheNames := d.Stats.CacheNames()
		sort.Strings(cacheNames)
		w.Write([]byte(fmt.Sprintf("Jump to:")))
		for _, cName := range cacheNames {
			w.Write([]byte(fmt.Sprintf("<a href=#%s>%s</a>  ", cName, cName)))
		}
		w.Write([]byte(fmt.Sprintf("\n")))
		for _, cName := range cacheNames {
			if showSelectCache && cName != cacheToDisplay {
				continue
			}
			w.Write([]byte(fmt.Sprintf("<a name=%s></a>", cName)))
			w.Write([]byte(fmt.Sprintf("\n\n<b>*** Cache \"%s\" ***</b>\n", cName)))
			keys := d.Stats.CacheKeys(cName)
			size, _ := d.Stats.CacheSizeByName(cName)
			capacity, _ := d.Stats.CacheCapacityByName(cName)
			w.Write([]byte(fmt.Sprintf("\n  * Size of in use cache:      %s \n", bytefmt.ByteSize(size))))
			w.Write([]byte(fmt.Sprintf("  * Cache capacity:            %s \n", bytefmt.ByteSize(capacity))))
			w.Write([]byte(fmt.Sprintf("  * Number of elements in LRU: %d\n", len(keys))))
			// tail is how much from the top of the LRU to display, top of the LRU is most recently used. head is the other side.
			head := 100
			tail := 100
			tailStr, ok := qstringOptions["tail"]
			if ok {
				tail, err = strconv.Atoi(tailStr[0])
				if err != nil {
					log.Errorf("Error converting tail value to int: %v", err)
				}
			}
			headStr, ok := qstringOptions["head"]
			if ok {
				head, err = strconv.Atoi(headStr[0])
				if err != nil {
					log.Errorf("Error converting head value to int: %v", err)
					head = 100
				}
			}

			w.Write([]byte(fmt.Sprintf("  * Objects in cache sorted by Least Recently Used on top, ")))
			if doSearch {
				w.Write([]byte(fmt.Sprintf("showing only strings matching %s:\n", searchArr[0])))
			} else {
				w.Write([]byte(fmt.Sprintf("showing only first %d and last %d:\n\n", head, tail)))
			}

			w.Write([]byte(fmt.Sprintf("<b>            #    Code      Size                   Age              FreshFor    HitCount      Key</b>\n")))
			for i, key := range keys {
				if (doSearch && !strings.Contains(key, searchArr[0])) || !doSearch && (i >= tail && i < len(keys)-head) {
					continue
				}

				cacheObject, _ := d.Stats.CachePeek(key, cName)
				age := time.Now().Sub(cacheObject.ReqRespTime)
				freshFor := rfc.FreshFor(cacheObject.RespHeaders, cacheObject.RespCacheControl, cacheObject.ReqRespTime, cacheObject.RespRespTime)
				w.Write([]byte(fmt.Sprintf("     %8d%8d%10s%22v%22v%12d      <a href=\"http://%s%s?key=%s&cache=%s\">%s</a>\n",
					i, cacheObject.Code, bytefmt.ByteSize(cacheObject.Size), age, freshFor, cacheObject.HitCount, req.Host, CacheStatsEndpoint, url.QueryEscape(key), cName, key)))
			}

		}
	}

	writeHTMLPageFooter(w)
	clientIP, _ := web.GetClientIPPort(req)
	now := time.Now()
	// TODO add eventId?
	log.EventRaw(atsEventLogStr(now, clientIP, d.Hostname, req.Host, d.Port, "-", d.Scheme, req.URL.String(), req.Method, req.Proto, respCode, now.Sub(reqTime), 0, 0, 0, true, true, getCacheHitStr(true, false), "-", "-", req.UserAgent(), req.Header.Get("X-Money-Trace"), 1))

	return true
}
