<commit_before>package yata

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"path/filepath"

	"github.com/skratchdot/open-golang/open"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/drive/v3"
)

const (
	GoogleDrive = iota
	Dropbox
)

const noServerMsgFmt = "I would love to %s your tasks %s a server, but I don't see any configured yet! If you want to configure a server, type `yata %s --help`"

// ServerManager TODO docs
type ServerManager interface {
	Push() error
	Fetch() error
}

// NoServerManager TODO docs
type NoServerManager struct{}

// GoogleDriveManager TODO docs
type GoogleDriveManager struct {
	cfgMgr *ConfigManager
}

// NewServerManager TODO docs
func NewServerManager(serverType int) ServerManager {
	switch serverType {
	case GoogleDrive:
		return &GoogleDriveManager{
			cfgMgr: NewConfigManager(),
		}
	default:
		return &NoServerManager{}
	}
}

// Push TODO docs
func (m NoServerManager) Push() error {
	return fmt.Errorf(noServerMsgFmt, "push", "to", "push")
}

// Fetch TODO docs
func (m NoServerManager) Fetch() error {
	return fmt.Errorf(noServerMsgFmt, "fetch", "from", "fetch")
}

// Push TODO docs
func (m GoogleDriveManager) Push() error {
	cfg, err := m.getConfig()
	if err != nil {
		return err
	}
	ctx := context.Background()
	client, err := m.getClient(ctx, cfg)
	if err != nil {
		return err
	}

	srv, err := drive.New(client)
	if err != nil {
		return err
	}

	fileMetadata := &drive.File{
		Name:    "tasks.json",
		Parents: []string{"appDataFolder"},
	}

	_, err = srv.Files.Create(fileMetadata).Do()
	if err != nil {
		return err
	}

	return nil
}

// Fetch TODO docs
func (m GoogleDriveManager) Fetch() error {
	return nil
}

func (m GoogleDriveManager) getConfig() (*oauth2.Config, error) {
	dirSrv := NewDirectoryService()
	secPath := filepath.Join(dirSrv.RootPath, m.cfgMgr.Config.GoogleDrive.SecretFile)

	dat, err := ioutil.ReadFile(secPath)
	if err != nil {
		return nil, err
	}

	return google.ConfigFromJSON(dat, drive.DriveAppdataScope)
}

func (m GoogleDriveManager) getClient(ctx context.Context, config *oauth2.Config) (*http.Client, error) {
	tok, err := m.tokenFromConfig()<commit_msg>Fixes #4<commit_after>package yata

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"

	"github.com/skratchdot/open-golang/open"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/drive/v3"
)

const (
	GoogleDrive = iota
	Dropbox
)

const noServerMsgFmt = "I would love to %s your tasks %s a server, but I don't see any configured yet! If you want to configure a server, type `yata %s --help`"

var PushableFiles = []struct {
	Name, Path string
}{
	{Name: "tasks.json", Path: NewDirectoryService().GetFullPath()},
	{Name: ".yataid", Path: NewDirectoryService().GetFullIDPath()},
}

// ServerManager TODO docs
type ServerManager interface {
	Push() error
	Fetch() error
}

// NoServerManager TODO docs
type NoServerManager struct{}

// GoogleDriveManager TODO docs
type GoogleDriveManager struct {
	cfgMgr *ConfigManager
}

// NewServerManager TODO docs
func NewServerManager(serverType int) ServerManager {
	switch serverType {
	case GoogleDrive:
		return &GoogleDriveManager{
			cfgMgr: NewConfigManager(),
		}
	default:
		return &NoServerManager{}
	}
}

// Push TODO docs
func (m NoServerManager) Push() error {
	return fmt.Errorf(noServerMsgFmt, "push", "to", "push")
}

// Fetch TODO docs
func (m NoServerManager) Fetch() error {
	return fmt.Errorf(noServerMsgFmt, "fetch", "from", "fetch")
}

// Push TODO docs
func (m GoogleDriveManager) Push() error {
	cfg, err := m.getConfig()
	if err != nil {
		return err
	}
	ctx := context.Background()
	client, err := m.getClient(ctx, cfg)
	if err != nil {
		return err
	}

	srv, err := drive.New(client)
	if err != nil {
		return err
	}

	return m.saveFiles(srv)

	fileMetadata := &drive.File{
		Name:    "tasks.json",
		Parents: []string{"appDataFolder"},
	}

	_, err = srv.Files.Create(fileMetadata).Do()
	if err != nil {
		return err
	}

	return nil
}

// Fetch TODO docs
func (m GoogleDriveManager) Fetch() error {
	return nil
}

func (m GoogleDriveManager) saveFiles(srv *drive.Service) error {
	fileList, err := srv.Files.List().Spaces("appDataFolder").Fields("nextPageToken, files(id, name)").PageSize(10).Do()
	if err != nil {
		return err
	}

	if len(fileList.Files) > 0 {
		for _, pf := range PushableFiles {
			var found bool

			fileMetadata := drive.File{
				Name:    pf.Name,
				Parents: []string{"appDataFolder"},
			}

			file, err := os.Open(pf.Path)
			if err != nil {
				return err
			}

			for _, f := range fileList.Files {
				if f.Name == pf.Name {
					found = true

					_, err = srv.Files.Update(f.Id, &fileMetadata).Media(file).Do()
					if err != nil {
						return err
					}

					break
				}
			}

			if !found {
				_, err = srv.Files.Create(&fileMetadata).Media(file).Do()
				if err != nil {
					return err
				}
			}
		}
	}

	return nil
}

func (m GoogleDriveManager) getConfig() (*oauth2.Config, error) {
	dirSrv := NewDirectoryService()
	secPath := filepath.Join(dirSrv.RootPath, m.cfgMgr.Config.GoogleDrive.SecretFile)

	dat, err := ioutil.ReadFile(secPath)
	if err != nil {
		return nil, err
	}

	return google.ConfigFromJSON(dat, drive.DriveAppdataScope)
}

func (m GoogleDriveManager) getClient(ctx context.Context, config *oauth2.Config) (*http.Client, error) {
	tok, err := m.tokenFromConfig()
{'fraction_non_alphanumeric': 0.136438961517216, 'fraction_numerical': 0.0025777941447247283, 'mean_word_length': 3.777484608619173, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, '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': '2844236', 'n_tokens_mistral': 2115, 'n_tokens_neox': 1927, 'n_words': 506}