package api

import (
	"fmt"
	"log"
	"net/http"
	"sync"

	"code.justin.tv/live/yt-live-annotations/youtube"
	jax "code.justin.tv/web/jax/client"

	"golang.org/x/net/context"
)

const (
	numWorkers = 20
)

func (s *Server) cleanupJob(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	go s.cleanup()

	s.serveSuccess(w, "cleanup")
}

func (s *Server) cleanup() {
	log.Printf("starting cleanup")

	idCh, errCh := s.backend.ScanAnnotationsEnabledUsers()
	ids := []string{}

loop:
	for {
		select {
		case id, more := <-idCh:
			if !more {
				break loop
			}
			ids = append(ids, id)
		case err := <-errCh:
			if err != nil {
				s.logError(fmt.Errorf("scan error on cleanup: %v", err))
				return
			}

		}
	}

	log.Printf("found %v users to clean up", len(ids))
	s.stats.Gauge("cleanup.users", int64(len(ids)), 1.0)

	var wg sync.WaitGroup
	wg.Add(numWorkers)

	notlive := 0
	ch := make(chan string, numWorkers)
	for i := 0; i < numWorkers; i++ {
		go func() {
			defer wg.Done()
			for id := range ch {
				stream, err := s.jax.GetStreamByID(context.Background(), id, &jax.StreamOptions{}, nil)
				if err == nil {
					if stream.TotalCount == 0 {
						if err := s.yt.SetYoutubeAnnotationsStatus(context.Background(), id, youtube.StatusDown); err != nil {
							s.logError(fmt.Errorf("failed to clean up annotation for %v: %v", id, err))
						}
						notlive++
					}
				}
			}
		}()
	}

	for _, id := range ids {
		ch <- id
	}
	close(ch)
	wg.Wait()

	// Report results
	log.Printf("done notlive: %v", notlive)
	s.stats.Gauge("cleanup.notlive", int64(notlive), 1.0)
}

func (s *Server) logError(err error) {
	if s.errorLogger != nil && !youtube.ShouldIgnoreError(err) {
		s.errorLogger.Error(err)
	}
}
