// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package present

import (
	"fmt"
	"html/template"
	"io/ioutil"
	"log"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"unicode"
)

// Is the playground available?
var PlayEnabled = false

// TOOD(adg): replace the PlayEnabled flag with something less spaghetti-like.
// Instead this will probably be determined by a template execution Context
// value that contains various global metadata required when rendering
// templates.

func init() {
	Register("code", parseCode)
	Register("play", parseCode)
}

type Code struct {
	Text template.HTML
	Play bool // runnable code
}

func (c Code) TemplateName() string { return "code" }

// The input line is a .code or .play entry with a file name and an optional HLfoo marker on the end.
// Anything between the file and HL (if any) is an address expression, which we treat as a string here.
// We pick off the HL first, for easy parsing.
var highlightRE = regexp.MustCompile(`\s+HL([a-zA-Z0-9_]+)?$`)
var codeRE = regexp.MustCompile(`\.(code|play)\s+([^\s]+)(\s+)?(.*)?$`)

func parseCode(sourceFile string, sourceLine int, cmd string) (Elem, error) {
	cmd = strings.TrimSpace(cmd)

	// Pull off the HL, if any, from the end of the input line.
	highlight := ""
	if hl := highlightRE.FindStringSubmatchIndex(cmd); len(hl) == 4 {
		highlight = cmd[hl[2]:hl[3]]
		cmd = cmd[:hl[2]-2]
	}

	// Parse the remaining command line.
	// Arguments:
	// args[0]: whole match
	// args[1]:  .code/.play
	// args[2]: file name
	// args[3]: space, if any, before optional address
	// args[4]: optional address
	args := codeRE.FindStringSubmatch(cmd)
	if len(args) != 5 {
		return nil, fmt.Errorf("%s:%d: syntax error for .code/.play invocation", sourceFile, sourceLine)
	}
	command, file, addr := args[1], args[2], strings.TrimSpace(args[4])
	play := command == "play" && PlayEnabled

	// Read in code file and (optionally) match address.
	filename := filepath.Join(filepath.Dir(sourceFile), file)
	textBytes, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, fmt.Errorf("%s:%d: %v", sourceFile, sourceLine, err)
	}
	lo, hi, err := addrToByteRange(addr, 0, textBytes)
	if err != nil {
		return nil, fmt.Errorf("%s:%d: %v", sourceFile, sourceLine, err)
	}

	// Acme pattern matches stop mid-line,
	// so run to end of line in both directions.
	for lo > 0 && textBytes[lo-1] != '\n' {
		lo--
	}
	for hi < len(textBytes) {
		hi++
		if textBytes[hi-1] == '\n' {
			break
		}
	}
	text := string(textBytes[lo:hi])

	// Clear ommitted lines.
	text = skipOMIT(text)

	// Replace tabs by spaces, which work better in HTML.
	text = strings.Replace(text, "\t", "    ", -1)

	// Escape the program text for HTML.
	text = template.HTMLEscapeString(text)

	// Highlight and span-wrap lines.
	text = "<pre>" + highlightLines(text, highlight) + "</pre>"

	// Include before and after in a hidden span for playground code.
	if play {
		text = hide(skipOMIT(string(textBytes[:lo]))) +
			text + hide(skipOMIT(string(textBytes[hi:])))
	}

	// Include the command as a comment.
	text = fmt.Sprintf("<!--{{%s}}\n-->%s", cmd, text)

	return Code{Text: template.HTML(text), Play: play}, nil
}

// skipOMIT turns text into a string, dropping lines ending with OMIT.
func skipOMIT(text string) string {
	lines := strings.SplitAfter(text, "\n")
	for k := range lines {
		if strings.HasSuffix(lines[k], "OMIT\n") {
			lines[k] = ""
		}
	}
	return strings.Join(lines, "")
}

func parseArgs(name string, line int, args []string) (res []interface{}, err error) {
	res = make([]interface{}, len(args))
	for i, v := range args {
		if len(v) == 0 {
			return nil, fmt.Errorf("%s:%d bad code argument %q", name, line, v)
		}
		switch v[0] {
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
			n, err := strconv.Atoi(v)
			if err != nil {
				return nil, fmt.Errorf("%s:%d bad code argument %q", name, line, v)
			}
			res[i] = n
		case '/':
			if len(v) < 2 || v[len(v)-1] != '/' {
				return nil, fmt.Errorf("%s:%d bad code argument %q", name, line, v)
			}
			res[i] = v
		case '$':
			res[i] = "$"
		default:
			return nil, fmt.Errorf("%s:%d bad code argument %q", name, line, v)
		}
	}
	return
}

// parseArg returns the integer or string value of the argument and tells which it is.
func parseArg(arg interface{}, file string, max int) (ival int, sval string, isInt bool) {
	switch n := arg.(type) {
	case int:
		if n <= 0 || n > max {
			log.Fatalf("%q:%d is out of range", file, n)
		}
		return n, "", true
	case string:
		return 0, n, false
	}
	log.Fatalf("unrecognized argument %v type %T", arg, arg)
	return
}

// oneLine returns the single line generated by a two-argument code invocation.
func oneLine(file, text string, arg interface{}) (line, before, after string, err error) {
	contentBytes, err := ioutil.ReadFile(file)
	if err != nil {
		return "", "", "", err
	}
	lines := strings.SplitAfter(string(contentBytes), "\n")
	lineNum, pattern, isInt := parseArg(arg, file, len(lines))
	var n int
	if isInt {
		n = lineNum - 1
	} else {
		n, err = match(file, 0, lines, pattern)
		n -= 1
	}
	if err != nil {
		return "", "", "", err
	}
	return lines[n],
		strings.Join(lines[:n], ""),
		strings.Join(lines[n+1:], ""),
		nil
}

// multipleLines returns the text generated by a three-argument code invocation.
func multipleLines(file string, arg1, arg2 interface{}) (line, before, after string, err error) {
	contentBytes, err := ioutil.ReadFile(file)
	lines := strings.SplitAfter(string(contentBytes), "\n")
	if err != nil {
		return "", "", "", err
	}
	line1, pattern1, isInt1 := parseArg(arg1, file, len(lines))
	line2, pattern2, isInt2 := parseArg(arg2, file, len(lines))
	if !isInt1 {
		line1, err = match(file, 0, lines, pattern1)
	}
	if !isInt2 {
		line2, err = match(file, line1, lines, pattern2)
	} else if line2 < line1 {
		return "", "", "", fmt.Errorf("lines out of order for %q: %d %d", file, line1, line2)
	}
	if err != nil {
		return "", "", "", err
	}
	for k := line1 - 1; k < line2; k++ {
		if strings.HasSuffix(lines[k], "OMIT\n") {
			lines[k] = ""
		}
	}
	return strings.Join(lines[line1-1:line2], ""),
		strings.Join(lines[:line1-1], ""),
		strings.Join(lines[line2:], ""),
		nil
}

// match identifies the input line that matches the pattern in a code invocation.
// If start>0, match lines starting there rather than at the beginning.
// The return value is 1-indexed.
func match(file string, start int, lines []string, pattern string) (int, error) {
	// $ matches the end of the file.
	if pattern == "$" {
		if len(lines) == 0 {
			return 0, fmt.Errorf("%q: empty file", file)
		}
		return len(lines), nil
	}
	// /regexp/ matches the line that matches the regexp.
	if len(pattern) > 2 && pattern[0] == '/' && pattern[len(pattern)-1] == '/' {
		re, err := regexp.Compile(pattern[1 : len(pattern)-1])
		if err != nil {
			return 0, err
		}
		for i := start; i < len(lines); i++ {
			if re.MatchString(lines[i]) {
				return i + 1, nil
			}
		}
		return 0, fmt.Errorf("%s: no match for %#q", file, pattern)
	}
	return 0, fmt.Errorf("unrecognized pattern: %q", pattern)
}

var hlRE = regexp.MustCompile(`(.+) // HL(.*)$`)

// highlightLines emboldens lines that end with "// HL" and
// wraps any other lines in span tags.
func highlightLines(text, label string) string {
	lines := strings.Split(text, "\n")
	for i, line := range lines {
		m := hlRE.FindStringSubmatch(line)
		if m == nil {
			continue
		}
		line := m[1]
		space := ""
		if j := strings.IndexFunc(line, func(r rune) bool {
			return !unicode.IsSpace(r)
		}); j > 0 {
			space = line[:j]
			line = line[j:]
		}
		if m[2] == "" || m[2] == label {
			lines[i] = space + "<b>" + line + "</b>"
		}
	}
	return strings.Join(lines, "\n")
}

func hide(text string) string {
	return fmt.Sprintf(`<pre style="display: none">%s</pre>`, template.HTMLEscapeString(text))
}
