package tests

import (
  "testing"
  "context"
  "fmt"
  "log"
  "time"
  "runtime"
  "github.com/stretchr/testify/require"
  browser "github.com/chromedp/chromedp"
)

type ZedBrowser struct {
  ctx context.Context
  require *require.Assertions
}

func (z *ZedBrowser) ClickOn(id string) {
  err := browser.Run(z.ctx, browser.WaitVisible(id),)
  z.require.NoError(err)

  resp, err := browser.RunResponse(z.ctx,
  browser.WaitVisible(id),
  browser.Click(id))

  z.require.NoError(err)
  z.require.Equal(resp.Status, int64(200))
}

func (z *ZedBrowser) GoTo(path string, expect string) {
  err := browser.Run(z.ctx,
  browser.Navigate(fmt.Sprintf(`http://127.0.0.1:5002%s`, path)),
  browser.WaitVisible(`body > footer`),
  browser.WaitVisible(expect))
  z.require.NoError(err)
}

func (z *ZedBrowser) WaitFor(expect string) {
  err := browser.Run(z.ctx, browser.WaitVisible(expect))
  z.require.NoError(err)
}

func (z *ZedBrowser) ExpectText(target string, expect string) {
  var extracted string
  err := browser.Run(z.ctx, browser.Text(target, &extracted))
  z.require.NoError(err)
  z.require.Equal(expect, extracted)
}

func (z *ZedBrowser) Run(actions ...browser.Action) {
  err := browser.Run(z.ctx, actions...)
  z.require.NoError(err)
}

func (z *ZedBrowser) TypeIn(id string, text string) {
  z.WaitFor(id)
  err := browser.Run(z.ctx, browser.SendKeys(id, text))
  z.require.NoError(err)
}

func Setup(t *testing.T, timeout time.Duration) (*ZedBrowser, context.CancelFunc) {
  opts := append(browser.DefaultExecAllocatorOptions[:],
    browser.Flag("headless", runtime.GOOS == "windows"),)

  ctx, cancel := browser.NewExecAllocator(context.Background(), opts...)

  ctx, _ = browser.NewContext(ctx, browser.WithLogf(log.Printf))

  ctx, _ = context.WithTimeout(ctx, timeout * time.Second)

  req := require.New(t)

  return &ZedBrowser{ctx, req}, cancel
}
