// Returns configuration and runtime information about the deployed application.
func GetSystemInfo(mgr *server.EntityManager, cfg AppConfig) webapp.HttpHandler {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")

		contentBuffer := mgr.ContentBuffer()
		entityStats := contentBuffer.LatestEntityStats()

		// If no content received from the content source within the last minute
		// or so, we deem it "offline".
		timeSinceLatestContentReceived := time.Since(entityStats.NewestContent.Time())
		isContentSourceOnline := timeSinceLatestContentReceived <= (1 * time.Minute)

		timeRangesInHours := []int{}
		for _, duration := range cfg.TimeRanges {
			timeRangesInHours = append(timeRangesInHours, int(duration/time.Hour))
		}

		itemCounts := map[string]int{
			"Documents": contentBuffer.DocumentCount(),
			"Persons":   contentBuffer.PersonGraph.EntityCount(),
			"Orgs":      contentBuffer.OrgGraph.EntityCount(),
			"Places":    contentBuffer.PlaceGraph.EntityCount(),
		}

		runtimeInfo := map[string]interface{}{
			"Errors":              mgr.RecentErrors(),
			"ItemCounts":          itemCounts,
			"ContentSourceOnline": isContentSourceOnline,
			"TimeRangesInHours":   timeRangesInHours,
			"OldestContent":       entityStats.OldestContent.String(),
			"NewestContent":       entityStats.NewestContent.String(),
		}

		deploymentInfo := map[string]interface{}{
			"Version":       GIT_VERSION,
			"BuildDate":     BUILD_DATE,
			"MemDbEndpoint": cfg.MemDbConn,
		}

		systemIinfo := map[string]interface{}{
			"Runtime":    runtimeInfo,
			"Deployment": deploymentInfo,
		}

		sendJsonResponse(systemIinfo, w)
	}
}