/*
 * Copyright 2020-present Open Networking Foundation

 * 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 flow

import (
	"bufio"
	"context"
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"testing"
)

// TestLoadersIdentical ensures that the group, flow, and meter loaders always have an identical implementation.
func TestLoadersIdentical(t *testing.T) {
	types := []string{"flow", "group"}

	identical := [][]string{
		{`ofp\.OfpFlowStats`, `ofp\.OfpGroupEntry`},
		{`\.Id`, `\.Desc\.GroupId`},
		{`uint64`, `uint32`},
		{`Flow`, `Group`},
		{`flow`, `group`},
	}

	regexes := make([][]*regexp.Regexp, len(identical[0]))
	for i := range regexes {
		regexes[i] = make([]*regexp.Regexp, len(identical))
	}
	for i, group := range identical {
		for j, regexStr := range group {
			// convert from column-wise to row-wise for convenience
			regexes[j][i] = regexp.MustCompile(regexStr)
		}
	}

	for i := 1; i < len(types); i++ {
		if err := compare(regexes[0], regexes[i],
			"../"+types[0]+"/cache.go",
			"../"+types[i]+"/cache.go"); err != nil {
			t.Error(err)
			return
		}
	}
}

func compare(regexesA, regexesB []*regexp.Regexp, fileNameA, fileNameB string) error {
	fileA, err := os.Open(filepath.Clean(fileNameA))
	if err != nil {
		return err
	}
	defer func() {
		err := fileA.Close()
		if err != nil {
			logger.Errorf(context.Background(), "failed to close file: %v", err)
		}
	}()

	fileB, err := os.Open(filepath.Clean(fileNameB))
	if err != nil {
		return err
	}
	defer func() {
		err := fileB.Close()
		if err != nil {
			logger.Errorf(context.Background(), "failed to close file: %v", err)
		}
	}()

	scannerA, scannerB := bufio.NewScanner(fileA), bufio.NewScanner(fileB)

	// treat any number of spaces as a single space
	spaceRegex := regexp.MustCompile(` +`)
	// extra lines are permitted before a "blank" line, or before a lock/unlock
	spacerRegex := regexp.MustCompile(`^(?:[^a-z]*|.*Lock\(\)|.*Unlock\(\))$`)
	// ignore import type differences
	libGoImportRegex := regexp.MustCompile(`^.*github\.com/opencord/voltha-protos/.*$`)

	lineA, lineB := 1, 1
linesLoop:
	for {
		if continueA, continueB := scannerA.Scan(), scannerB.Scan(); !continueA || !continueB {
			// EOF
			break linesLoop
		}
		textA, textB := scannerA.Text(), scannerB.Text()

		// allow any number of "extra" lines just before a spacer line
		for {
			isSpacerA, isSpacerB := spacerRegex.MatchString(textA), spacerRegex.MatchString(textB)
			if isSpacerA && !isSpacerB {
				if !scannerB.Scan() {
					// EOF
					break linesLoop
				}
				lineB++
				textB = scannerB.Text()
				continue
			} else if isSpacerB && !isSpacerA {
				if !scannerA.Scan() {
					// EOF
					break linesLoop
				}
				lineA++
				textA = scannerA.Text()
				continue
			}
			break
		}

		replacedA, replacedB := textA, textB
		for i := range regexesA {
			replacement := "{{type" + strconv.Itoa(i) + "}}"
			replacedA, replacedB = regexesA[i].ReplaceAllString(replacedA, replacement), regexesB[i].ReplaceAllString(replacedB, replacement)
		}

		// replace multiple spaces with single space
		replacedA, replacedB = spaceRegex.ReplaceAllString(replacedA, " "), spaceRegex.ReplaceAllString(replacedB, " ")

		// ignore voltha-protos import of ofp vs voltha
		replacedA, replacedB = libGoImportRegex.ReplaceAllString(replacedA, "{{lib-go-import}}"), libGoImportRegex.ReplaceAllString(replacedB, "{{lib-go-import}}")

		if replacedA != replacedB && textA != textB {
			return fmt.Errorf("files which must be identical do not match: \n  %s:%d\n    %s\n  %s:%d\n    %s\n\n\t%s\n\t%s", fileNameA, lineA, textA, fileNameB, lineB, textB, replacedA, replacedB)
		}

		lineA++
		lineB++
	}

	if err := scannerA.Err(); err != nil {
		return err
	}
	if err := scannerB.Err(); err != nil {
		return err
	}
	return nil
}
