// goredo -- djb's redo implementation on pure Go
// Copyright (C) 2020-2026 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package main

import (
	"errors"
	"io/fs"
)

func sourcesWalker(
	tgts []*Tgt,
	seen map[string]struct{},
	seenDeps map[string]struct{},
	srcs map[string]*Tgt,
) error {
	for _, tgt := range tgts {
		if _, ok := seenDeps[tgt.rel]; ok {
			continue
		}
		seenDeps[tgt.rel] = struct{}{}
		dep, err := depRead(tgt)
		if err != nil {
			if errors.Is(err, fs.ErrNotExist) {
				continue
			}
			return ErrLine(err)
		}
		for _, ifchange := range dep.ifchanges {
			if _, ok := seen[ifchange.tgt.rel]; ok {
				continue
			}
			seen[ifchange.tgt.rel] = struct{}{}
			if isSrc(ifchange.tgt) {
				srcs[ifchange.tgt.rel] = ifchange.tgt
			} else if ifchange.tgt.rel != tgt.rel {
				if err := sourcesWalker(
					[]*Tgt{ifchange.tgt},
					seen, seenDeps, srcs,
				); err != nil {
					return err
				}
			}
		}
	}
	return nil
}
