You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: schemadocs.go
    path of file: ./repos/juju/scripts/schemadocs
    
    the code of the file until where you have to start completion: // Copyright 2019 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package main

import (
	"encoding/json"
	"fmt"
	"html/template"
	"log"
	"os"
	"sort"
	"strings"
)

func main() {
	// the first argument here will be the name of the binary, so we ignore
	// argument 0 when looking for the filepath.
	if len(os.Args) != 2 {
		fmt.Fprintln(os.Stderr, "Expected one argument: filepath of json schema to read.")
		os.Exit(1)
	}

	data, err := os.ReadFile(os.Args[1])
	if err != nil {
		log.Fatal(err)
	}

	var input []JSONFacade
	if err := json.Unmarshal(data, &input); err != nil {
		log.Fatal(err)
	}

	sort.Slice(input, func(i, j int) bool {
		f1, f2 := input[i], input[j]
		if f1.Name != f2.Name {
			return f1.Name < f2.Name
		}
		return f1.Version > f2.Version
	})

	output := make([]TemplateFacade, len(input))
	for k, facade := range input {
		methods := make([]TemplateMethod, 0, len(facade.Schema.Properties))
		for k, prop := range facade.Schema.Properties {
			methods = append(methods, TemplateMethod{
				Name:        k,
				Description: prop.Description,
				Param:       prop.Properties.Params.Ref,
				Result:      prop.Properties.Result.Ref,
			})
		}
		sort.Slice(methods, func(i, j int) bool {
			return methods[i].Name < methods[j].Name
		})

		definitions := make([]TemplateDefinition, 0, len(facade.Schema.Definitions))
		for k, prop := range facade.Schema.Definitions {
			properties := make([]TemplateProperty, 0, len(prop.Properties))
			for k, v := range prop.Properties {
				ref := v.Ref.Ref
				if v.Type == "array" {
					if v.Items.Type != "" {
						ref = v.Items.Type
					} else {
						ref = v.Items.Ref
					}
				}
				properties = append(properties, TemplateProperty{
					Name:   k,
					Type:   v.Type,
					Format: v.Format,
					Ref:    ref,
				})
			}
			sort.Slice(properties, func(i, j int) bool {
				return properties[i].Name < properties[j].Name
			})

			definitions = append(definitions, TemplateDefinition{
				Name:       k,
				Type:       prop.Type,
				Properties: properties,
			})
		}
		sort.Slice(definitions, func(i, j int) bool {
			return definitions[i].Name < definitions[j].Name
		})

		output[k] = TemplateFacade
    
func main() {
	// the first argument here will be the name of the binary, so we ignore
	// argument 0 when looking for the filepath.
	if len(os.Args) != 2 {
		fmt.Fprintln(os.Stderr, "Expected one argument: filepath of json schema to read.")
		os.Exit(1)
	}

	data, err := os.ReadFile(os.Args[1])
	if err != nil {
		log.Fatal(err)
	}

	var input []JSONFacade
	if err := json.Unmarshal(data, &input); err != nil {
		log.Fatal(err)
	}

	sort.Slice(input, func(i, j int) bool {
		f1, f2 := input[i], input[j]
		if f1.Name != f2.Name {
			return f1.Name < f2.Name
		}
		return f1.Version > f2.Version
	})

	output := make([]TemplateFacade, len(input))
	for k, facade := range input {
		methods := make([]TemplateMethod, 0, len(facade.Schema.Properties))
		for k, prop := range facade.Schema.Properties {
			methods = append(methods, TemplateMethod{
				Name:        k,
				Description: prop.Description,
				Param:       prop.Properties.Params.Ref,
				Result:      prop.Properties.Result.Ref,
			})
		}
		sort.Slice(methods, func(i, j int) bool {
			return methods[i].Name < methods[j].Name
		})

		definitions := make([]TemplateDefinition, 0, len(facade.Schema.Definitions))
		for k, prop := range facade.Schema.Definitions {
			properties := make([]TemplateProperty, 0, len(prop.Properties))
			for k, v := range prop.Properties {
				ref := v.Ref.Ref
				if v.Type == "array" {
					if v.Items.Type != "" {
						ref = v.Items.Type
					} else {
						ref = v.Items.Ref
					}
				}
				properties = append(properties, TemplateProperty{
					Name:   k,
					Type:   v.Type,
					Format: v.Format,
					Ref:    ref,
				})
			}
			sort.Slice(properties, func(i, j int) bool {
				return properties[i].Name < properties[j].Name
			})

			definitions = append(definitions, TemplateDefinition{
				Name:       k,
				Type:       prop.Type,
				Properties: properties,
			})
		}
		sort.Slice(definitions, func(i, j int) bool {
			return definitions[i].Name < definitions[j].Name
		})

		output[k] = TemplateFacade{
			Name:        facade.Name,
			AvailableTo: facade.AvailableTo,
			Description: facade.Description,
			Version:     facade.Version,
			Methods:     methods,
			Definitions: definitions,
		}
	}

	t, err := template.New("").Funcs(tmplFuncs).Parse(htmlTmpl)
	if err != nil {
		log.Fatal(err)
	}
	if err := t.Execute(os.Stdout, output); err != nil {
		log.Fatal(err)
	}
}