<commit_before>package service

import (
	"context"
	"time"

	"github.com/tidepool-org/platform/data/summary"

	"github.com/tidepool-org/platform/data"
	dataStore "github.com/tidepool-org/platform/data/store"
	"github.com/tidepool-org/platform/errors"
	"github.com/tidepool-org/platform/log"
	"github.com/tidepool-org/platform/page"
)

const (
	backfillBatch = 100000
)

type Client struct {
	dataStore dataStore.Store
}

func NewClient(strDEPRECATED dataStore.Store) (*Client, error) {
	if strDEPRECATED == nil {
		return nil, errors.New("data store deprecated is missing")
	}

	return &Client{
		dataStore: strDEPRECATED,
	}, nil
}

func (c *Client) CreateUserDataSet(ctx context.Context, userID string, create *data.DataSetCreate) (*data.DataSet, error) {
	panic("Not Implemented!")
}

func (c *Client) ListUserDataSets(ctx context.Context, userID string, filter *data.DataSetFilter, pagination *page.Pagination) (data.DataSets, error) {
	repository := c.dataStore.NewDataRepository()
	return repository.ListUserDataSets(ctx, userID, filter, pagination)
}

func (c *Client) GetDataSet(ctx context.Context, id string) (*data.DataSet, error) {
	repository := c.dataStore.NewDataRepository()
	return repository.GetDataSet(ctx, id)
}

func (c *Client) GetSummary(ctx context.Context, id string) (*summary.Summary, error) {
	summaryRepository := c.dataStore.NewSummaryRepository()
	return summaryRepository.GetSummary(ctx, id)
}

func (c *Client) UpdateSummary(ctx context.Context, id string) (*summary.Summary, error) {
	var err error
	var status *summary.UserLastUpdated
	var userSummary *summary.Summary
	var timestamp time.Time
	timestamp = time.Now().UTC()
	logger := log.LoggerFromContext(ctx)
	logger.Debugf("Starting summary calculation for %s", id)
	summaryRepository := c.dataStore.NewSummaryRepository()
	dataRepository := c.dataStore.NewDataRepository()

	// we need the original summary object to grab the original for rolling calc
	userSummary, err = summaryRepository.GetSummary(ctx, id)
	if err != nil {
		return nil, err
	}

	status, err = dataRepository.GetLastUpdatedForUser(ctx, id)
	if err != nil {
		return nil, err
	}

	if status == nil {
		if userSummary != nil {
			// user's data is inactive/deleted, or this summary shouldn't have been created
			logger.Warnf("User %s has an outdated summary with no data, skipping calc.", id)
			userSummary.OutdatedSince = nil

			userSummary.LastUpdatedDate = &timestamp
			userSummary, err = summaryRepository.UpdateSummary(ctx, userSummary)
			if err != nil {
				return nil, err
			}
		}
		return userSummary, nil
	}

	// user exists (has relevant data), but no summary, create a blank one
	if userSummary == nil {
		userSummary = summary.New(id)
	}

	// remove 2 weeks for start time
	startTime := status.LastData.AddDate(0, 0, -14)

	// if summary already exists with a last data checkpoint, start data pull there
	if userSummary.LastData != nil {
		if startTime.Before(*userSummary.LastData) {
			startTime = *userSummary.LastData
		}
	}

	userData, err := dataRepository.GetCGMDataRange(ctx, id, startTime, status.LastData)
	if err != nil {
		return nil, err
	}
<commit_msg>correct some ugly whitespace<commit_after>package service

import (
	"context"
	"time"

	"github.com/tidepool-org/platform/data/summary"

	"github.com/tidepool-org/platform/data"
	dataStore "github.com/tidepool-org/platform/data/store"
	"github.com/tidepool-org/platform/errors"
	"github.com/tidepool-org/platform/log"
	"github.com/tidepool-org/platform/page"
)

const (
	backfillBatch = 100000
)

type Client struct {
	dataStore dataStore.Store
}

func NewClient(strDEPRECATED dataStore.Store) (*Client, error) {
	if strDEPRECATED == nil {
		return nil, errors.New("data store deprecated is missing")
	}

	return &Client{
		dataStore: strDEPRECATED,
	}, nil
}

func (c *Client) CreateUserDataSet(ctx context.Context, userID string, create *data.DataSetCreate) (*data.DataSet, error) {
	panic("Not Implemented!")
}

func (c *Client) ListUserDataSets(ctx context.Context, userID string, filter *data.DataSetFilter, pagination *page.Pagination) (data.DataSets, error) {
	repository := c.dataStore.NewDataRepository()
	return repository.ListUserDataSets(ctx, userID, filter, pagination)
}

func (c *Client) GetDataSet(ctx context.Context, id string) (*data.DataSet, error) {
	repository := c.dataStore.NewDataRepository()
	return repository.GetDataSet(ctx, id)
}

func (c *Client) GetSummary(ctx context.Context, id string) (*summary.Summary, error) {
	summaryRepository := c.dataStore.NewSummaryRepository()
	return summaryRepository.GetSummary(ctx, id)
}

func (c *Client) UpdateSummary(ctx context.Context, id string) (*summary.Summary, error) {
	var err error
	var status *summary.UserLastUpdated
	var userSummary *summary.Summary
	var timestamp time.Time
	timestamp = time.Now().UTC()
	logger := log.LoggerFromContext(ctx)
	logger.Debugf("Starting summary calculation for %s", id)
	summaryRepository := c.dataStore.NewSummaryRepository()
	dataRepository := c.dataStore.NewDataRepository()

	// we need the original summary object to grab the original for rolling calc
	userSummary, err = summaryRepository.GetSummary(ctx, id)
	if err != nil {
		return nil, err
	}

	status, err = dataRepository.GetLastUpdatedForUser(ctx, id)
	if err != nil {
		return nil, err
	}

	if status == nil {
		if userSummary != nil {
			// user's data is inactive/deleted, or this summary shouldn't have been created
			logger.Warnf("User %s has an outdated summary with no data, skipping calc.", id)
			userSummary.OutdatedSince = nil
			userSummary.LastUpdatedDate = &timestamp

			userSummary, err = summaryRepository.UpdateSummary(ctx, userSummary)
			if err != nil {
				return nil, err
			}
		}
		return userSummary, nil
	}

	// user exists (has relevant data), but no summary, create a blank one
	if userSummary == nil {
		userSummary = summary.New(id)
	}

	// remove 2 weeks for start time
	startTime := status.LastData.AddDate(0, 0, -14)

	// if summary already exists with a last data checkpoint, start data pull there
	if userSummary.LastData != nil {
		if startTime.Before(*userSummary.LastData) {
			startTime = *userSummary.LastData
		}
	}

	userData, err := dataRepository.GetCGMDataRange(ctx, id, startTime, status.LastData)
	if err != nil {
		return nil, err
	}

{'fraction_non_alphanumeric': 0.11299793683542295, 'fraction_numerical': 0.0034915092842405966, 'mean_word_length': 4.616755793226382, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3842304', 'n_tokens_mistral': 2085, 'n_tokens_neox': 1988, 'n_words': 551}