// Copyright 2016 Google Inc. All rights reserved.
//
// 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.

// cookie parses curl cookie jar files.
package cookie

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/fsnotify/fsnotify"
)

// ParseCookieJar parses a cURL/Mozilla/Netscape cookie jar text file.
func ParseCookieJar(r io.Reader) ([]*http.Cookie, error) {
	var result []*http.Cookie
	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		line := scanner.Text()
		httpOnly := false
		const httpOnlyPrefix = "#HttpOnly_"
		if strings.HasPrefix(line, httpOnlyPrefix) {
			line = line[len(httpOnlyPrefix):]
			httpOnly = true
		}
		if strings.HasPrefix(line, "#") {
			continue
		}
		line = strings.TrimSpace(line)

		if line == "" {
			continue
		}
		fields := strings.Split(line, "\t")
		if len(fields) != 7 {
			return nil, fmt.Errorf("got %d fields in line %q, want 8", len(fields), line)
		}

		exp, err := strconv.ParseInt(fields[4], 10, 64)
		if err != nil {
			return nil, err
		}

		c := http.Cookie{
			Domain:   fields[0],
			Name:     fields[5],
			Value:    fields[6],
			Path:     fields[2],
			Expires:  time.Unix(exp, 0),
			Secure:   fields[3] == "TRUE",
			HttpOnly: httpOnly,
		}

		result = append(result, &c)
	}

	return result, nil
}

// WatchJar starts watching the given path for changes, and loads new
// data from the file whenever it is available.
func WatchJar(jar http.CookieJar, path string) error {
	w, err := fsnotify.NewWatcher()
	if err != nil {
		return err
	}

	// We watch the dir, so we catch creation + rename events too.
	if err := w.Add(filepath.Dir(path)); err != nil {
		return err
	}

	go func() {
		var lastMod time.Time
		for {
			select {
			case <-w.Events:
				fi, err := os.Stat(path)
				if os.IsNotExist(err) {
					continue
				}

				if err != nil {
					log.Printf("Stat(%s): %v", path, err)
					continue
				}
				if fi.ModTime().Equal(lastMod) {
					continue
				}
				lastMod = fi.ModTime()
				if err := updateJar(jar, path); err != nil {
					log.Printf("updateJar(%s): %v", path, err)
				}

			case <-w.Errors:
				log.Printf("notify (%s):  %v", path, err)
			}
		}
	}()
	return nil
}

// updateJar reads the path into the jar.
func updateJar(jar http.CookieJar, path string) error {
	f, err := os.Open(path)
	if err != nil {
		return err
	}
	defer f.Close()

	cs, err := ParseCookieJar(f)
	if err != nil {
		return err
	}

	for _, c := range cs {
		jar.SetCookies(&url.URL{
			Scheme: "http",
			Host:   c.Domain,
		}, []*http.Cookie{c})
	}

	return nil
}

// NewJar reads cookies in the Mozilla/Netscape cookie file format,
// and returns them as a CookieJar
func NewJar(path string) (http.CookieJar, error) {
	jar, err := cookiejar.New(nil)
	if err != nil {
		return nil, err
	}

	if err := updateJar(jar, path); err != nil {
		return nil, err
	}

	return jar, nil
}
