// 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"
	"errors"
	"strings"
)

type pattern struct {
	prefix, suffix string
}

func (p pattern) String() string {
	return p.prefix + "%" + p.suffix
}

func (p pattern) match(s string) bool {
	return strings.HasPrefix(s, p.prefix) && strings.HasSuffix(s, p.suffix)
}

func (p pattern) subst(repl, str string) string {
	in := str
	trimed := str
	if p.prefix != "" {
		trimed = strings.TrimPrefix(in, p.prefix)
		if trimed == in {
			return str
		}
	}
	in = trimed
	if p.suffix != "" {
		trimed = strings.TrimSuffix(in, p.suffix)
		if trimed == in {
			return str
		}
	}
	rs := strings.SplitN(repl, "%", 2)
	if len(rs) != 2 {
		return repl
	}
	return rs[0] + trimed + rs[1]
}

type rule struct {
	srcpos
	outputs         []string
	inputs          []string
	orderOnlyInputs []string
	outputPatterns  []pattern
	isDoubleColon   bool
	isSuffixRule    bool
	cmds            []string
	cmdLineno       int
}

func (r *rule) cmdpos() srcpos {
	return srcpos{filename: r.filename, lineno: r.cmdLineno}
}

func isPatternRule(s []byte) (pattern, bool) {
	i := bytes.IndexByte(s, '%')
	if i < 0 {
		return pattern{}, false
	}
	return pattern{prefix: string(s[:i]), suffix: string(s[i+1:])}, true
}

func (r *rule) parseInputs(s []byte) {
	ws := newWordScanner(s)
	isOrderOnly := false
	for ws.Scan() {
		input := ws.Bytes()
		if len(input) == 1 && input[0] == '|' {
			isOrderOnly = true
			continue
		}
		if isOrderOnly {
			r.orderOnlyInputs = append(r.orderOnlyInputs, internBytes(input))
		} else {
			r.inputs = append(r.inputs, internBytes(input))
		}
	}
}

func (r *rule) parseVar(s []byte) (*assignAST, error) {
	eq := bytes.IndexByte(s, '=')
	if eq <= 0 {
		return nil, nil
	}
	rhs := trimLeftSpaceBytes(s[eq+1:])
	var lhs []byte
	var op string
	// TODO(ukai): support override, export.
	switch s[eq-1] { // s[eq] is '='
	case ':':
		lhs = trimSpaceBytes(s[:eq-1])
		op = ":="
	case '+':
		lhs = trimSpaceBytes(s[:eq-1])
		op = "+="
	case '?':
		lhs = trimSpaceBytes(s[:eq-1])
		op = "?="
	default:
		lhs = trimSpaceBytes(s[:eq])
		op = "="
	}
	assign, err := newAssignAST(nil, lhs, rhs, op)
	if err != nil {
		return nil, err
	}
	assign.srcpos = r.srcpos
	return assign, nil
}

func (r *rule) parse(line []byte) (*assignAST, error) {
	index := bytes.IndexByte(line, ':')
	if index < 0 {
		return nil, errors.New("*** missing separator.")
	}

	first := line[:index]
	ws := newWordScanner(first)
	pat, isFirstPattern := isPatternRule(first)
	if isFirstPattern {
		n := 0
		for ws.Scan() {
			n++
			if n > 1 {
				return nil, errors.New("*** mixed implicit and normal rules: deprecated syntax")
			}
		}
		r.outputPatterns = []pattern{pat}
	} else {
		for ws.Scan() {
			r.outputs = append(r.outputs, internBytes(ws.Bytes()))
		}
	}

	index++
	if index < len(line) && line[index] == ':' {
		r.isDoubleColon = true
		index++
	}

	rest := line[index:]
	assign, err := r.parseVar(rest)
	if err != nil {
		return nil, err
	}
	if assign != nil {
		return assign, nil
	}
	index = bytes.IndexByte(rest, ':')
	if index < 0 {
		r.parseInputs(rest)
		return nil, nil
	}

	// %.x: %.y: %.z
	if isFirstPattern {
		return nil, errors.New("*** mixed implicit and normal rules: deprecated syntax")
	}

	second := rest[:index]
	third := rest[index+1:]

	// r.outputs is already set.
	ws = newWordScanner(second)
	if !ws.Scan() {
		return nil, errors.New("*** missing target pattern.")
	}
	outpat, ok := isPatternRule(ws.Bytes())
	if !ok {
		return nil, errors.New("*** target pattern contains no '%'.")
	}
	r.outputPatterns = []pattern{outpat}
	if ws.Scan() {
		return nil, errors.New("*** multiple target patterns.")
	}
	r.parseInputs(third)

	return nil, nil
}
