<commit_before>// Copyright 2016 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package rebuild

import (
	"net/url"
	"strings"

	"github.com/tsuru/tsuru/log"
	"github.com/tsuru/tsuru/router"
	appTypes "github.com/tsuru/tsuru/types/app"
)

type RebuildRoutesResult struct {
	Added   []string
	Removed []string
}

type RebuildApp interface {
	router.App
	GetCname() []string
	GetRouters() []appTypes.AppRouter
	GetHealthcheckData() (router.HealthcheckData, error)
	RoutableAddresses() ([]url.URL, error)
	InternalLock(string) (bool, error)
	Unlock()
}

func RebuildRoutes(app RebuildApp, dry bool) (map[string]RebuildRoutesResult, error) {
	result := make(map[string]RebuildRoutesResult)
	for _, appRouter := range app.GetRouters() {
		resultInRouter, err := rebuildRoutesInRouter(app, dry, appRouter)
		if err != nil {
			return nil, err
		}
		result[appRouter.Name] = *resultInRouter
	}
	return result, nil
}

func rebuildRoutesInRouter(app RebuildApp, dry bool, appRouter appTypes.AppRouter) (*RebuildRoutesResult, error) {
	log.Debugf("[rebuild-routes] rebuilding routes for app %q", app.GetName())
	r, err := router.Get(appRouter.Name)
	if err != nil {
		return nil, err
	}
	if optsRouter, ok := r.(router.OptsRouter); ok {
		err = optsRouter.AddBackendOpts(app, appRouter.Opts)
	} else {
		err = r.AddBackend(app)
	}
	if err != nil && err != router.ErrBackendExists {
		return nil, err
	}
	if cnameRouter, ok := r.(router.CNameRouter); ok {
		for _, cname := range app.GetCname() {
			err = cnameRouter.SetCName(cname, app.GetName())
			if err != nil && err != router.ErrCNameExists {
				return nil, err
			}
		}
	}
	if hcRouter, ok := r.(router.CustomHealthcheckRouter); ok {
		hcData, err := app.GetHealthcheckData()
		if err != nil {
			return nil, err
		}
		err = hcRouter.SetHealthcheck(app.GetName(), hcData)
		if err != nil {
			return nil, err
		}
	}
	oldRoutes, err := r.Routes(app.GetName())
	if err != nil {
		return nil, err
	}
	log.Debugf("[rebuild-routes] old routes for app %q: %v", app.GetName(), oldRoutes)
	expectedMap := make(map[string]*url.URL)
	addresses, err := app.RoutableAddresses()
	if err != nil {
		return nil, err
	}
	log.Debugf("[rebuild-routes] addresses for app %q: %v", app.GetName(), addresses)
	for i, addr := range addresses {
		expectedMap[addr.Host] = &addresses[i]
	}
	var toRemove []*url.URL
	for _, url := range oldRoutes {
		if _, isPresent := expectedMap[url.Host]; isPresent {
			delete(expectedMap, url.Host)
		} else {
			toRemove = append(toRemove, url)
		}
	}<commit_msg>router/rebuild: fix variable shadowing<commit_after>// Copyright 2016 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package rebuild

import (
	"net/url"
	"strings"

	"github.com/tsuru/tsuru/log"
	"github.com/tsuru/tsuru/router"
	appTypes "github.com/tsuru/tsuru/types/app"
)

type RebuildRoutesResult struct {
	Added   []string
	Removed []string
}

type RebuildApp interface {
	router.App
	GetCname() []string
	GetRouters() []appTypes.AppRouter
	GetHealthcheckData() (router.HealthcheckData, error)
	RoutableAddresses() ([]url.URL, error)
	InternalLock(string) (bool, error)
	Unlock()
}

func RebuildRoutes(app RebuildApp, dry bool) (map[string]RebuildRoutesResult, error) {
	result := make(map[string]RebuildRoutesResult)
	for _, appRouter := range app.GetRouters() {
		resultInRouter, err := rebuildRoutesInRouter(app, dry, appRouter)
		if err != nil {
			return nil, err
		}
		result[appRouter.Name] = *resultInRouter
	}
	return result, nil
}

func rebuildRoutesInRouter(app RebuildApp, dry bool, appRouter appTypes.AppRouter) (*RebuildRoutesResult, error) {
	log.Debugf("[rebuild-routes] rebuilding routes for app %q", app.GetName())
	r, err := router.Get(appRouter.Name)
	if err != nil {
		return nil, err
	}
	if optsRouter, ok := r.(router.OptsRouter); ok {
		err = optsRouter.AddBackendOpts(app, appRouter.Opts)
	} else {
		err = r.AddBackend(app)
	}
	if err != nil && err != router.ErrBackendExists {
		return nil, err
	}
	if cnameRouter, ok := r.(router.CNameRouter); ok {
		for _, cname := range app.GetCname() {
			err = cnameRouter.SetCName(cname, app.GetName())
			if err != nil && err != router.ErrCNameExists {
				return nil, err
			}
		}
	}
	if hcRouter, ok := r.(router.CustomHealthcheckRouter); ok {
		hcData, errHc := app.GetHealthcheckData()
		if errHc != nil {
			return nil, errHc
		}
		errHc = hcRouter.SetHealthcheck(app.GetName(), hcData)
		if errHc != nil {
			return nil, errHc
		}
	}
	oldRoutes, err := r.Routes(app.GetName())
	if err != nil {
		return nil, err
	}
	log.Debugf("[rebuild-routes] old routes for app %q: %v", app.GetName(), oldRoutes)
	expectedMap := make(map[string]*url.URL)
	addresses, err := app.RoutableAddresses()
	if err != nil {
		return nil, err
	}
	log.Debugf("[rebuild-routes] addresses for app %q: %v", app.GetName(), addresses)
	for i, addr := range addresses {
		expectedMap[addr.Host] = &addresses[i]
	}
	var toRemove []*url.URL
	for _, url := range oldRoutes {
		if _, isPresent := expectedMap[url.Host]; isPresent {
			delete(expectedMap, url.Host)
		} else {
			toRemove = append(toRemove, url)
		}
	}
{'fraction_non_alphanumeric': 0.13757816941444, 'fraction_numerical': 0.0015160128861095318, 'mean_word_length': 4.099516908212561, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5799519', 'n_tokens_mistral': 1985, 'n_tokens_neox': 1903, 'n_words': 479}