/*
 * 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", "meter"}

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

	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
}
