// Copyright 2019 The Wuffs Authors.
//
// 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
//
//    https://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.

//go:build ignore
// +build ignore

package main

// print-markdown-links.go prints a sorted list of the link targets in the
// given .md files (or directories containing .md files).
//
// Usage: go run print-markdown-links.go dirname0 filename1 etc
//
// For link targets that look like "/file/names" (as opposed to starting with
// web URLs starting with "http:" or "https:"), they are preceded by a '+' or a
// '-' depending on whether or not that file or directory exists, assuming that
// this script is run in the root directory to resolve filename links that
// start with a slash.
//
// Printing web URLs can be skipped entirely by passing -skiphttp
//
// For example, running:
//   go run script/print-markdown-links.go -skiphttp doc | grep "^-"
// can find broken Markdown links in the documentation.

import (
	"flag"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"sort"
	"strings"

	"github.com/russross/blackfriday/v2"
)

var skiphttp = flag.Bool("skiphttp", false, `skip "http:" or "https:" links`)

func main() {
	if err := main1(); err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(1)
	}
}

func main1() error {
	flag.Parse()
	r := &renderer{
		links: map[string]struct{}{},
	}

	for _, arg := range flag.Args() {
		err := filepath.Walk(arg, func(path string, info os.FileInfo, walkErr error) error {
			if walkErr != nil {
				return walkErr
			}
			if info.IsDir() || !strings.HasSuffix(path, ".md") {
				return nil
			}
			return visit(r, path)
		})
		if err != nil {
			return err
		}
	}

	sorted := make([]string, 0, len(r.links))
	for k := range r.links {
		sorted = append(sorted, k)
	}
	sort.Strings(sorted)

	for _, s := range sorted {
		mark := '-'
		switch {
		case strings.HasPrefix(s, "http:"), strings.HasPrefix(s, "https:"):
			if *skiphttp {
				continue
			}
			mark = ':'
		case (len(s) > 0) && (s[0] == '/'):
			filename := s[1:]
			if i := strings.IndexByte(filename, '#'); i >= 0 {
				filename = filename[:i]
			}
			if _, err := os.Stat(filename); err == nil {
				mark = '+'
			}
		}
		fmt.Printf("%c %s\n", mark, s)
	}
	return nil
}

func visit(r *renderer, filename string) error {
	src, err := os.ReadFile(filename)
	if err != nil {
		return err
	}
	blackfriday.Run(src, blackfriday.WithRenderer(r))
	return nil
}

type renderer struct {
	links map[string]struct{}
}

func (r *renderer) RenderHeader(w io.Writer, n *blackfriday.Node) {}
func (r *renderer) RenderFooter(w io.Writer, n *blackfriday.Node) {}

func (r *renderer) RenderNode(w io.Writer, n *blackfriday.Node, entering bool) blackfriday.WalkStatus {
	if entering {
		if dst := n.LinkData.Destination; len(dst) != 0 {
			r.links[string(dst)] = struct{}{}
		}
	}
	return blackfriday.GoToNext
}
