// 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.

// slothfs-gitiles-test is a program executing a single gitiles HTTP
// request, to be used for troubleshooting proxy/auth problems.
package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"sync"

	"github.com/google/slothfs/gitiles"
)

func main() {
	gitilesURL := flag.String("gitiles", "", "URL for gitiles")
	cookieJarPath := flag.String("cookies", "", "path to cURL-style cookie jar file.")
	agent := flag.String("agent", "slothfs-expand", "gitiles User-Agent string to use.")
	tap := flag.Bool("tap", false, "if set, tap traffic exchanged with $http_proxy")
	flag.Parse()

	if *tap {
		tapTraffic()
	}
	if *gitilesURL == "" {
		log.Fatal("must set --gitiles")
	}

	opts := gitiles.Options{
		UserAgent: *agent,
	}
	if err := opts.LoadCookieJar(*cookieJarPath); err != nil {
		log.Fatalf("LoadCookieJar(%s): %v", *cookieJarPath, err)
	}

	service, err := gitiles.NewService(*gitilesURL, opts)
	if err != nil {
		log.Fatalf("NewService: %v", err)
	}

	projs, err := service.List(nil)
	if err != nil {
		log.Fatalf("List: %v", err)
	}

	for p := range projs {
		fmt.Printf("project: %s\n", p)
	}
}

func logCopy(w io.Writer, r io.Reader, who string) {
	var buf [320000]byte

	for {
		n, e1 := r.Read(buf[:])
		log.Println(who, string(buf[:n]))
		_, e2 := w.Write(buf[:n])
		if e1 != nil || e2 != nil {
			break
		}
	}
}

func forward(conn net.Conn, addr string) {
	f, err := net.Dial("tcp", addr)
	if err != nil {
		log.Fatal(err)
	}

	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		logCopy(f, conn, "A")
		wg.Done()
	}()
	go func() {
		logCopy(conn, f, "B")
		wg.Done()
	}()
	wg.Wait()
	f.Close()
	conn.Close()
}

func tapTraffic() {
	proxy := os.Getenv("http_proxy")
	if proxy == "" {
		log.Println("no http_proxy, not tapping")
		return
	}

	l, err := net.Listen("tcp", ":0")
	if err != nil {
		log.Fatal(err)
	}
	os.Setenv("http_proxy", l.Addr().String())

	go func() {
		for {
			c, err := l.Accept()
			if err != nil {
				break
			}
			go forward(c, proxy)
		}
	}()
}
