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

package kati

import (
	"bytes"
	"path/filepath"
	"strings"

	"github.com/golang/glog"
)

var wsbytes = [256]bool{' ': true, '\t': true, '\n': true, '\r': true}

// TODO(ukai): use unicode.IsSpace?
func isWhitespace(ch rune) bool {
	if int(ch) >= len(wsbytes) {
		return false
	}
	return wsbytes[ch]
}

func splitSpaces(s string) []string {
	var r []string
	tokStart := -1
	for i, ch := range s {
		if isWhitespace(ch) {
			if tokStart >= 0 {
				r = append(r, s[tokStart:i])
				tokStart = -1
			}
		} else {
			if tokStart < 0 {
				tokStart = i
			}
		}
	}
	if tokStart >= 0 {
		r = append(r, s[tokStart:])
	}
	glog.V(2).Infof("splitSpace(%q)=%q", s, r)
	return r
}

func splitSpacesBytes(s []byte) (r [][]byte) {
	tokStart := -1
	for i, ch := range s {
		if isWhitespace(rune(ch)) {
			if tokStart >= 0 {
				r = append(r, s[tokStart:i])
				tokStart = -1
			}
		} else {
			if tokStart < 0 {
				tokStart = i
			}
		}
	}
	if tokStart >= 0 {
		r = append(r, s[tokStart:])
	}
	glog.V(2).Infof("splitSpace(%q)=%q", s, r)
	return r
}

// TODO(ukai): use bufio.Scanner?
type wordScanner struct {
	in []byte
	s  int // word starts
	i  int // current pos
}

func newWordScanner(in []byte) *wordScanner {
	return &wordScanner{
		in: in,
	}
}

func (ws *wordScanner) next() bool {
	for ws.s = ws.i; ws.s < len(ws.in); ws.s++ {
		if !wsbytes[ws.in[ws.s]] {
			break
		}
	}
	if ws.s == len(ws.in) {
		return false
	}
	return true
}

func (ws *wordScanner) Scan() bool {
	if !ws.next() {
		return false
	}
	for ws.i = ws.s; ws.i < len(ws.in); ws.i++ {
		if wsbytes[ws.in[ws.i]] {
			break
		}
	}
	return true
}

func (ws *wordScanner) Bytes() []byte {
	return ws.in[ws.s:ws.i]
}

func (ws *wordScanner) Remain() []byte {
	if !ws.next() {
		return nil
	}
	return ws.in[ws.s:]
}

func matchPattern(pat, str string) bool {
	i := strings.IndexByte(pat, '%')
	if i < 0 {
		return pat == str
	}
	return strings.HasPrefix(str, pat[:i]) && strings.HasSuffix(str, pat[i+1:])
}

func matchPatternBytes(pat, str []byte) bool {
	i := bytes.IndexByte(pat, '%')
	if i < 0 {
		return bytes.Equal(pat, str)
	}
	return bytes.HasPrefix(str, pat[:i]) && bytes.HasSuffix(str, pat[i+1:])
}

func substPattern(pat, repl, str string) string {
	ps := strings.SplitN(pat, "%", 2)
	if len(ps) != 2 {
		if str == pat {
			return repl
		}
		return str
	}
	in := str
	trimed := str
	if ps[0] != "" {
		trimed = strings.TrimPrefix(in, ps[0])
		if trimed == in {
			return str
		}
	}
	in = trimed
	if ps[1] != "" {
		trimed = strings.TrimSuffix(in, ps[1])
		if trimed == in {
			return str
		}
	}

	rs := strings.SplitN(repl, "%", 2)
	if len(rs) != 2 {
		return repl
	}
	return rs[0] + trimed + rs[1]
}

func substPatternBytes(pat, repl, str []byte) (pre, subst, post []byte) {
	i := bytes.IndexByte(pat, '%')
	if i < 0 {
		if bytes.Equal(str, pat) {
			return repl, nil, nil
		}
		return str, nil, nil
	}
	in := str
	trimed := str
	if i > 0 {
		trimed = bytes.TrimPrefix(in, pat[:i])
		if bytes.Equal(trimed, in) {
			return str, nil, nil
		}
	}
	in = trimed
	if i < len(pat)-1 {
		trimed = bytes.TrimSuffix(in, pat[i+1:])
		if bytes.Equal(trimed, in) {
			return str, nil, nil
		}
	}

	i = bytes.IndexByte(repl, '%')
	if i < 0 {
		return repl, nil, nil
	}

	return repl[:i], trimed, repl[i+1:]
}

func substRef(pat, repl, str string) string {
	if strings.IndexByte(pat, '%') >= 0 && strings.IndexByte(repl, '%') >= 0 {
		return substPattern(pat, repl, str)
	}
	str = strings.TrimSuffix(str, pat)
	return str + repl
}

func stripExt(s string) string {
	suf := filepath.Ext(s)
	return s[:len(s)-len(suf)]
}

func trimLeftSpace(s string) string {
	for i, ch := range s {
		if !isWhitespace(ch) {
			return s[i:]
		}
	}
	return ""
}

func trimLeftSpaceBytes(s []byte) []byte {
	for i, ch := range s {
		if !isWhitespace(rune(ch)) {
			return s[i:]
		}
	}
	return nil
}

func trimRightSpaceBytes(s []byte) []byte {
	for i := len(s) - 1; i >= 0; i-- {
		ch := s[i]
		if !isWhitespace(rune(ch)) {
			return s[:i+1]
		}
	}
	return nil
}

func trimSpaceBytes(s []byte) []byte {
	s = trimLeftSpaceBytes(s)
	return trimRightSpaceBytes(s)
}

// Strip leading sequences of './' from file names, so that ./file
// and file are considered to be the same file.
// From http://www.gnu.org/software/make/manual/make.html#Features
func trimLeadingCurdir(s string) string {
	for strings.HasPrefix(s, "./") {
		s = s[2:]
	}
	return s
}

func contains(list []string, s string) bool {
	for _, v := range list {
		if v == s {
			return true
		}
	}
	return false
}

func firstWord(line []byte) ([]byte, []byte) {
	s := newWordScanner(line)
	if s.Scan() {
		w := s.Bytes()
		return w, s.Remain()
	}
	return line, nil
}

func findLiteralChar(s []byte, stop1, stop2 byte) int {
	i := 0
	for {
		var ch byte
		for i < len(s) {
			ch = s[i]
			if ch == '\\' {
				i += 2
				continue
			}
			if ch == stop1 {
				break
			}
			if ch == stop2 {
				break
			}
			if ch == '$' {
				break
			}
			i++
		}
		if i >= len(s) {
			return -1
		}
		if ch == '$' {
			i++
			if i == len(s) {
				return -1
			}
			oparen := s[i]
			cparen := closeParen(oparen)
			i++
			if cparen != 0 {
				pcount := 1
			SkipParen:
				for i < len(s) {
					ch = s[i]
					switch ch {
					case oparen:
						pcount++
					case cparen:
						pcount--
						if pcount == 0 {
							i++
							break SkipParen
						}
					}
					i++
				}
			}
			continue
		}
		return i
	}
}

func removeComment(line []byte) ([]byte, bool) {
	var buf []byte
	for i := 0; i < len(line); i++ {
		if line[i] != '#' {
			continue
		}
		b := 1
		for ; i-b >= 0; b++ {
			if line[i-b] != '\\' {
				break
			}
		}
		b++
		nb := b / 2
		quoted := b%2 == 1
		if buf == nil {
			buf = make([]byte, len(line))
			copy(buf, line)
			line = buf
		}
		line = append(line[:i-b+nb+1], line[i:]...)
		if !quoted {
			return line[:i-b+nb+1], true
		}
		i = i - nb + 1
	}
	return line, false
}

// cmdline removes tab at the beginning of lines.
func cmdline(line string) string {
	buf := []byte(line)
	for i := 0; i < len(buf); i++ {
		if buf[i] == '\n' && i+1 < len(buf) && buf[i+1] == '\t' {
			copy(buf[i+1:], buf[i+2:])
			buf = buf[:len(buf)-1]
		}
	}
	return string(buf)
}

// concatline removes backslash newline.
// TODO: backslash baskslash newline becomes backslash newline.
func concatline(line []byte) []byte {
	var buf []byte
	for i := 0; i < len(line); i++ {
		if line[i] != '\\' {
			continue
		}
		if i+1 == len(line) {
			if line[i-1] != '\\' {
				line = line[:i]
			}
			break
		}
		if line[i+1] == '\n' {
			if buf == nil {
				buf = make([]byte, len(line))
				copy(buf, line)
				line = buf
			}
			oline := trimRightSpaceBytes(line[:i])
			oline = append(oline, ' ')
			nextline := trimLeftSpaceBytes(line[i+2:])
			line = append(oline, nextline...)
			i = len(oline) - 1
			continue
		}
		if i+2 < len(line) && line[i+1] == '\r' && line[i+2] == '\n' {
			if buf == nil {
				buf = make([]byte, len(line))
				copy(buf, line)
				line = buf
			}
			oline := trimRightSpaceBytes(line[:i])
			oline = append(oline, ' ')
			nextline := trimLeftSpaceBytes(line[i+3:])
			line = append(oline, nextline...)
			i = len(oline) - 1
			continue
		}
	}
	return line
}
