// Copyright 2020 Google LLC
//
// 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.

//go:build go1.15
// +build go1.15

package main

import (
	"bufio"
	"context"
	"encoding/json"
	"log"
	"net/http"
	"strings"
	"time"
)

// indexer gets a limited list of entries from index.golang.org.
type indexer interface {
	get(prefixes []string, since time.Time) (entries []indexEntry, last time.Time, err error)
}

// indexClient is used to access index.golang.org.
type indexClient struct{}

var _ indexer = indexClient{}

// indexEntry represents a line in the output of index.golang.org/index.
type indexEntry struct {
	Path      string
	Version   string
	Timestamp time.Time
}

// newModules returns the new modules with the given prefix.
//
// newModules uses index.golang.org/index?since=timestamp to find new module
// versions since the given timestamp.
//
// newModules stores the timestamp of the last successful run with tSaver.
func newModules(ctx context.Context, i indexer, tSaver timeSaver, prefixes []string) ([]indexEntry, error) {
	since, err := tSaver.get(ctx)
	if err != nil {
		return nil, err
	}
	fiveMinAgo := time.Now().Add(-5 * time.Minute).UTC() // When to stop processing.
	entries := []indexEntry{}
	log.Printf("Fetching index.golang.org entries since %s", since.Format(time.RFC3339))
	count := 0
	for {
		count++
		var cur []indexEntry
		cur, since, err = i.get(prefixes, since)
		if err != nil {
			return nil, err
		}
		entries = append(entries, cur...)
		if since.After(fiveMinAgo) {
			break
		}
	}
	log.Printf("Parsed %d index.golang.org pages up to %s", count, since.Format(time.RFC3339))
	if err := tSaver.put(ctx, since); err != nil {
		return nil, err
	}

	return entries, nil
}

// get fetches a single chronological page of modules from
// index.golang.org/index.
func (indexClient) get(prefixes []string, since time.Time) ([]indexEntry, time.Time, error) {
	entries := []indexEntry{}
	sinceString := since.Format(time.RFC3339)
	resp, err := http.Get("https://index.golang.org/index?since=" + sinceString)
	if err != nil {
		return nil, time.Time{}, err
	}

	s := bufio.NewScanner(resp.Body)
	last := time.Time{}
	for s.Scan() {
		e := indexEntry{}
		if err := json.Unmarshal(s.Bytes(), &e); err != nil {
			return nil, time.Time{}, err
		}
		last = e.Timestamp // Always update the last timestamp.
		if !hasPrefix(e.Path, prefixes) ||
			strings.Contains(e.Path, "internal") ||
			strings.Contains(e.Path, "third_party") ||
			strings.Contains(e.Version, "-") { // Filter out pseudo-versions.
			continue
		}
		entries = append(entries, e)
	}
	return entries, last, nil
}
