text:
// Copyright 2019 the orbs-ethereum-contracts authors
// This file is part of the orbs-ethereum-contracts library in the Orbs project.
//
// This source code is licensed under the MIT license found in the LICENSE file in the root directory of this source tree.
// The above notice should be included in all copies or substantial portions of the software.

package elections_systemcontract

import (
	"fmt"
	"github.com/orbs-network/orbs-contract-sdk/go/sdk/v1/state"
	. "github.com/orbs-network/orbs-contract-sdk/go/testing/unit"
	"github.com/stretchr/testify/require"
	"testing"
)

func TestOrbsVotingContract_getStakeFromEthereum(t *testing.T) {
	addr := [20]byte{0x01}
	blockNumber := uint64(100)
	stakeSetup := 64

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		_setProcessCurrentElection(0, blockNumber, 0)
		mockStakeInEthereum(m, blockNumber, addr, stakeSetup)

		// call
		stake := _getStakeAtElection(addr)

		// assert
		m.VerifyMocks()
		require.EqualValues(t, stakeSetup, stake)
	})
}

func TestOrbsVotingContract_getLockedStakeFromEthereum(t *testing.T) {
	addr := [20]byte{0x01}
	blockNumber := uint64(100)
	stakeSetup := 64

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		_setProcessCurrentElection(0, blockNumber, 0)
		mockLockedStakeInEthereum(m, blockNumber, addr, stakeSetup)

		// call
		stake := _getLockedStakeAtElection(addr)

		// assert
		m.VerifyMocks()
		require.EqualValues(t, stakeSetup, stake)
	})
}

func TestOrbsVotingContract_processVote_processVoteMachine_CalulateStakes(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)
	aRecentVoteBlock := h.electionBlock - 1
	anAncientVoteBlock := uint64(10000)

	var v1, v2, v3, v4, v5 = h.addValidator(), h.addValidator(), h.addValidator(), h.addValidator(), h.addValidator()
	var g1, g2, g3, g4, g5 = h.addGuardian(100), h.addGuardian(200), h.addGuardian(400), h.addGuardian(1000), h.addGuardian(10000000)

	g1.vote(aRecentVoteBlock, v2, v1)
	g2.vote(aRecentVoteBlock, v2, v1)
	g3.vote(aRecentVoteBlock, v2, v3)
	g4.vote(aRecentVoteBlock, v2, v5)
	g5.vote(anAncientVoteBlock, v4)

	for i := 0; i < 10; i++ {
		h.addDelegator(500, g3.address)
	}

	d1 := h.addDelegator(500, g4.address)
	d2 := h.addDelegator(500, d1.address)
	h.addDelegator(500, d2.address)

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()
		h.setupEthereumStateBeforeProcess(m)

		// call
		expectedNumOfStateTransitions := len(h.guardians) + len(h.delegators) + len(h.validators) + 2
		elected, actualRuns := h.runProcessVoteMachineNtimes(expectedNumOfStateTransitions)

		// assert
		m.VerifyMocks()
		require.True(t, actualRuns <= expectedNumOfStateTransitions, "did not finish in correct amount of passes")
		require.EqualValues(t, "", _getVotingProcessState())
		require.ElementsMatch(t, [][20]byte{v1.address, v3.address, v4.address, v5.address}, elected)
	})
}

func TestOrbsVotingContract_processVote_processVoteMachine_CalulateStakesWithLocked(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = 60000
	aRecentVoteBlock := h.electionBlock - 1

	var v1, v2, v3, v4, v5 = h.addValidator(), h.addValidator(), h.addValidator(), h.addValidator(), h.addValidator()
	var g1, g2, g3, g4 = h.addGuardian(100), h.addGuardian(200), h.addGuardian(400), h.addGuardian(1000)

	g1.vote(aRecentVoteBlock, v2, v1)
	g2.vote(aRecentVoteBlock, v2, v1)
	g3.vote(aRecentVoteBlock, v2, v3)
	g4.vote(aRecentVoteBlock, v2, v5)

	for i := 0; i < 10; i++ {
		h.addDelegator(500, g3.address)
	}

	d1 := h.addDelegator(500, g4.address).withLockedStake(100000)
	d2 := h.addDelegator(500, d1.address)
	h.addDelegator(500, d2.address)

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()
		h.setupEthereumStateBeforeProcess(m)

		// call
		expectedNumOfStateTransitions := len(h.guardians) + len(h.delegators) + len(h.validators) + 2
		elected, actualRuns := h.runProcessVoteMachineNtimes(expectedNumOfStateTransitions)

		// assert
		m.VerifyMocks()
		require.True(t, actualRuns <= expectedNumOfStateTransitions, "did not finish in correct amount of passes")
		require.EqualValues(t, "", _getVotingProcessState())
		require.ElementsMatch(t, [][20]byte{v1.address, v3.address, v4.address}, elected)
	})
}

func TestOrbsVotingContract_processVote_processVoteMachine_BeforeAndAfterOnlyLocked(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = 10368900
	aRecentVoteBlock := h.electionBlock - 1

	var v1, v2, v3, v4, v5 = h.addValidator(), h.addValidator(), h.addValidator(), h.addValidator(), h.addValidator()
	var g1, g2, g3, g4 = h.addGuardian(10000), h.addGuardian(10000), h.addGuardian(50), h.addGuardian(10000)

	g1.vote(aRecentVoteBlock, v2, v3)
	g2.vote(aRecentVoteBlock, v2, v1)
	g3.vote(aRecentVoteBlock, v2, v4)
	g4.vote(aRecentVoteBlock, v2, v5)

	for i := 0; i < 10; i++ {
		h.addDelegator(500, g3.address).withLockedStake(1000)
	}

//	d1 := h.addDelegator(500, g4.address).withLockedStake(100000)
//	d2 := h.addDelegator(500, d1.address)
//	h.addDelegator(500, d2.address)

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()
		h.setupEthereumStateBeforeProcess(m)

		// first run
		expectedNumOfStateTransitions := len(h.guardians) + len(h.delegators) + len(h.validators) + 2
		elected, _ := h.runProcessVoteMachineNtimes(expectedNumOfStateTransitions)
		require.EqualValues(t, "", _getVotingProcessState())
		require.ElementsMatch(t, [][20]byte{v1.address,v3.address, v4.address, v5.address}, elected)

		// second run
		h.electionBlock = h.electionBlock+1
		_setProcessCurrentElection(h.electionTime, h.electionBlock, h.electionBlock-VOTE_VALID_PERIOD_LENGTH_IN_BLOCKS)
		h.setupEthereumStateBeforeProcess(m)
		elected, _ = h.runProcessVoteMachineNtimes(expectedNumOfStateTransitions)

		// assert
		require.EqualValues(t, "", _getVotingProcessState())
		require.ElementsMatch(t, [][20]byte{v1.address, v3.address, v5.address}, elected)
	})
}

func TestOrbsVotingContract_processVote_processVoteMachineWithTimeBased_CalulateStakes(t *testing.T) {
	h := newHarnessTimeBased()
	h.electionBlock = 60000
	aRecentVoteBlock := h.electionBlock - 1
	anAncientVoteBlock := uint64(1)

	var v1, v2, v3, v4, v5 = h.addValidator(), h.addValidator(), h.addValidator(), h.addValidator(), h.addValidator()
	var g1, g2, g3, g4, g5 = h.addGuardian(100), h.addGuardian(200), h.addGuardian(400), h.addGuardian(1000), h.addGuardian(10000000)

	g1.vote(aRecentVoteBlock, v2, v1)
	g2.vote(aRecentVoteBlock, v2, v1)
	g3.vote(aRecentVoteBlock, v2, v3)
	g4.vote(aRecentVoteBlock, v2, v5)
	g5.vote(anAncientVoteBlock, v4)

	for i := 0; i < 10; i++ {
		h.addDelegator(500, g3.address)
	}

	d1 := h.addDelegator(500, g4.address)
	d2 := h.addDelegator(500, d1.address)
	h.addDelegator(500, d2.address)

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()
		h.setupEthereumStateBeforeProcess(m)

		// call
		expectedNumOfStateTransitions := len(h.guardians) + len(h.delegators) + len(h.validators) + 2
		elected, actualRuns := h.runProcessVoteMachineNtimes(expectedNumOfStateTransitions)

		// assert
		m.VerifyMocks()
		require.True(t, actualRuns <= expectedNumOfStateTransitions, "did not finish in correct amount of passes")
		require.EqualValues(t, "", _getVotingProcessState())
		require.ElementsMatch(t, [][20]byte{v1.address, v3.address, v4.address, v5.address}, elected)
	})
}

func TestOrbsVotingContract_processVote_processVoteMachine_CalulateStakes_GuardianIsNotGuardian(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)
	aRecentVoteBlock := h.electionBlock - 1

	var v1 = h.addValidator()
	var g1, g2 = h.addGuardian(100000), h.addGuardian(10000).withIsGuardian(false)

	g1.vote(aRecentVoteBlock, v1)
	g2.vote(aRecentVoteBlock, v1)

	d1 := h.addDelegator(100000, g1.address)
	h.addDelegator(100000, g1.address)
	d3 := h.addDelegator(10000, g2.address)
	h.addDelegator(10000, g2.address)

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()
		h.setupEthereumStateBeforeProcess(m)

		// call
		h.runProcessVoteMachineNtimes(0)

		// assert
		m.VerifyMocks()
		require.EqualValues(t, 300000, getGuardianVotingWeight(g1.address[:]))
		require.True(t, 0 != getCumulativeParticipationReward(d1.address[:]))
		require.EqualValues(t, 0, getGuardianVotingWeight(g2.address[:]))
		require.EqualValues(t, 0, getCumulativeParticipationReward(d3.address[:]))
	})
}

func TestOrbsVotingContract_processVote_processVoteMachine_CalulateStakes_DelegatorIsGuardian(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)
	aRecentVoteBlock := h.electionBlock - 1

	v1 := h.addValidator()
	g1, g2, g3, g4 := h.addGuardian(10), h.addGuardian(100), h.addGuardian(1000), h.addGuardian(10000000)
	fakeD1 := h.addGuardian(10000)
	fakeD2 := h.addGuardian(100000)
	fakeD3 := h.addGuardian(1000000)

	g1.vote(aRecentVoteBlock, v1)
	g2.vote(aRecentVoteBlock, v1)
	g3.vote(aRecentVoteBlock, v1)
	g4.vote(aRecentVoteBlock, v1)

	// direct delegate from delegator that is guardian to a guardian
	d1 := &delegator{actor: actor{stake: fakeD1.stake, address: fakeD1.address}, delegate: g1.address}
	h.delegators = append(h.delegators, d1)

	// delegate from delegator that is guardian to real delegator to a guardian
	realD2 := h.addDelegator(1, g2.address)
	d2 := &delegator{actor: actor{stake: fakeD2.stake, address: fakeD2.address}, delegate: realD2.address}
	h.delegators = append(h.delegators, d2)

	// delegate from real delegator to delegator that is guardian to a guardian
	d3 := &delegator{actor: actor{stake: fakeD3.stake, address: fakeD3.address}, delegate: g3.address}
	h.delegators = append(h.delegators, d3)
	realD3 := h.addDelegator(1, fakeD3.address)

	// direct delegate from delegator that is guardian who voted to a guardian
	d4 := &delegator{actor: actor{stake: g4.stake, address: g4.address}, delegate: g1.address}
	h.delegators = append(h.delegators, d4)

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()
		h.setupEthereumValidatorsBeforeProcess(m)
		mockGuardiansInEthereum(m, h.electionBlock, h.guardians)
		h.setupEthereumGuardiansDataBeforeProcess(m)
		h.mockStakedAndLockedInEthereum(m, h.electionBlock, realD2.address, realD2.stake, realD2.lockedStake)
		h.mockStakedAndLockedInEthereum(m, h.electionBlock, realD3.address, realD3.stake, realD3.lockedStake)

		// call
		expectedNumOfStateTransitions := len(h.guardians) + len(h.delegators) + len(h.validators) + 3
		_, actualRuns := h.runProcessVoteMachineNtimes(expectedNumOfStateTransitions)

		// assert
		//m.VerifyMocks()
		require.True(t, actualRuns <= expectedNumOfStateTransitions, "did not finish in correct amount of passes")
		require.EqualValues(t, 10, getGuardianVotingWeight(g1.address[:]))
		require.EqualValues(t, 101, getGuardianVotingWeight(g2.address[:]))
		require.EqualValues(t, 1000, getGuardianVotingWeight(g3.address[:]))
		require.EqualValues(t, 10000000, getGuardianVotingWeight(g4.address[:]))
		require.EqualValues(t, 0, getGuardianVotingWeight(fakeD1.address[:]))
		require.EqualValues(t, 0, getGuardianVotingWeight(fakeD2.address[:]))
		require.EqualValues(t, 0, getGuardianVotingWeight(fakeD3.address[:]))
		require.EqualValues(t, 0, getCumulativeParticipationReward(realD3.address[:]))
		require.EqualValues(t, 1, state.ReadUint64(_formatDelegatorStakeKey(realD2.address[:])))
		require.EqualValues(t, 1, state.ReadUint64(_formatDelegatorStakeKey(realD3.address[:])))
	})
}

func TestOrbsVotingContract_processVote_ValidatorsFromEthereumToState(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)
	v1, v2 := h.addValidator(), h.addValidator()
	validators := [][20]byte{v1.address, v2.address}

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()
		mockValidatorsInEthereum(m, h.electionBlock, validators)

		// call
		_readValidatorsFromEthereumToState()
		stateValidators := _getValidators()

		// assert
		m.VerifyMocks()
		require.EqualValues(t, len(h.validators), _getNumberOfValidators())
		for i := 0; i < _getNumberOfValidators(); i++ {
			require.EqualValues(t, h.validators[i].address, _getValidatorEthereumAddressAtIndex(i))
		}
		require.EqualValues(t, len(h.validators), len(stateValidators))
		for i := 0; i < len(h.validators); i++ {
			require.EqualValues(t, h.validators[i].address, stateValidators[i])
		}
	})
}

func TestOrbsVotingContract_processVote_collectValidatorDataFromEthereum(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)

	var v1, v2 = h.addValidatorWithStake(100), h.addValidatorWithStake(200)

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()
		mockValidatorOrbsAddressInEthereum(m, h.electionBlock, v1.address, v1.orbsAddress)
		h.mockStakedAndLockedInEthereum(m, h.electionBlock, v1.address, 250, 250)
		mockValidatorOrbsAddressInEthereum(m, h.electionBlock, v2.address, v2.orbsAddress)
		h.mockStakedAndLockedInEthereum(m, h.electionBlock, v2.address, 450, 450)
		_setVotingProcessItem(0)

		// call
		i := 0
		for ; i < 2; i++ {
			_collectNextValidatorDataFromEthereum()
		}

		// assert
		m.VerifyMocks()
		require.EqualValues(t, i, _getVotingProcessItem())
		require.EqualValues(t, 500, state.ReadUint64(_formatValidatorStakeKey(v1.address[:])))
		require.EqualValues(t, v1.orbsAddress[:], state.ReadBytes(_formatValidatorOrbsAddressKey(v1.address[:])))
		require.EqualValues(t, 900, state.ReadUint64(_formatValidatorStakeKey(v2.address[:])))
		require.EqualValues(t, v2.orbsAddress[:], state.ReadBytes(_formatValidatorOrbsAddressKey(v2.address[:])))
	})
}

func TestOrbsVotingContract_processVote_readGuardiansFromEthereum(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)

	var g1, g2 = h.addGuardian(100), h.addGuardian(200)

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()
		mockGuardiansInEthereum(m, h.electionBlock, h.guardians)
		_setGuardianStake(_formatGuardianStakeKey(g1.address[:]), 500)

		// call
		_readGuardiansFromEthereumToState()
		guardians := _getGuardians()

		// assert
		m.VerifyMocks()
		require.EqualValues(t, 2, _getNumberOfGuardians())
		require.EqualValues(t, g1.address, _getGuardianAtIndex(0))
		require.EqualValues(t, g2.address, _getGuardianAtIndex(1))
		require.EqualValues(t, 2, len(guardians))
		require.True(t, guardians[g1.address])
		require.True(t, guardians[g2.address])
	})
}

func TestOrbsVotingContract_processVote_readGuardiansFromEthereumWithPaging(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)

	for i := 0; i < 55; i++ {
		h.addGuardian(100)
	}

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		mockGuardiansInEthereum(m, h.electionBlock, h.guardians)
		h.setupOrbsStateBeforeProcessMachine()

		// call
		_readGuardiansFromEthereumToState()
		guardians := _getGuardians()

		// assert
		m.VerifyMocks()
		require.EqualValues(t, 55, _getNumberOfGuardians())
		require.EqualValues(t, 55, len(guardians))
	})
}

func TestOrbsVotingContract_processVote_collectOneGuardianStakeFromEthereum_NoStateAddr_DoesntFail(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)

	InServiceScope(nil, nil, func(m Mockery) {
		_init()
		h.setupOrbsStateBeforeProcessMachine()
		mockGuardianVoteInEthereum(m, h.electionBlock, [20]byte{}, [][20]byte{}, 0)

		// call
		_collectOneGuardianDataFromEthereum(0)

		// assert
		m.VerifyMocks()
	})
}

func TestOrbsVotingContract_processVote_collectGuardiansStakeFromEthereum(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)
	aRecentVoteBlock := h.electionBlock - 1

	var v1 = h.addValidator()
	var g1, g2 = h.addGuardian(400), h.addGuardian(600)
	g1.lockedStake = 500

	g1.vote(aRecentVoteBlock, v1)
	g2.vote(aRecentVoteBlock, v1)

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()
		h.setupEthereumGuardiansDataBeforeProcess(m)
		_setVotingProcessItem(0)

		// call
		i := 0
		for ; i < 2; i++ {
			_collectNextGuardiansDataFromEthereum()
		}

		// assert
		m.VerifyMocks()
		require.EqualValues(t, i, _getVotingProcessItem())
		require.EqualValues(t, 900, state.ReadUint64(_formatGuardianStakeKey(g1.address[:])))
		require.ElementsMatch(t, [][20]byte{v1.address}, _getCandidates(g1.address[:]))
		require.EqualValues(t, 600, state.ReadUint64(_formatGuardianStakeKey(g2.address[:])))
		require.ElementsMatch(t, [][20]byte{v1.address}, _getCandidates(g2.address[:]))
	})
}

func TestOrbsVotingContract_processVote_collectGuardiansDataFromEthereum_AncientVoterStakeIs0(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)
	anAncientVoteBlock := uint64(10000)

	var v1 = h.addValidator()
	var g3, g4 = h.addGuardian(100), h.addGuardian(200)

	g3.vote(anAncientVoteBlock, v1)
	g4.vote(0, v1) // fake didn't vote

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()
		h.setupEthereumGuardiansDataBeforeProcess(m)

		_setVotingProcessItem(0)

		// call
		i := 0
		for ; i < 2; i++ {
			_collectNextGuardiansDataFromEthereum()
		}

		// assert
		m.VerifyMocks()
		require.EqualValues(t, g3.address, _getGuardianAtIndex(0))
		require.EqualValues(t, 0, state.ReadUint64(_formatGuardianStakeKey(g3.address[:])))
		require.ElementsMatch(t, [][20]byte{{}}, _getCandidates(g3.address[:]))
		require.EqualValues(t, g4.address, _getGuardianAtIndex(1))
		require.EqualValues(t, 0, state.ReadUint64(_formatGuardianStakeKey(g4.address[:])))
		require.ElementsMatch(t, [][20]byte{{}}, _getCandidates(g4.address[:]))
	})
}

func TestOrbsVotingContract_processVote_collectOneDelegatorStakeFromEthereum_NoStateAddr_DoesntFail(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()
		h.mockStakedAndLockedInEthereum(m, h.electionBlock, [20]byte{}, 0, 0)

		// call
		_collectOneDelegatorStakeFromEthereum(0)

		// assert
		m.VerifyMocks()
	})
}

func TestOrbsVotingContract_processVote_collectOneDelegatorStakeFromEthereum_IsGuardian_Stake0(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)

	var g1 = h.addGuardian(100).withIsGuardian(true)

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()
		_setDelegatorAtIndex(0, g1.address[:])
		state.WriteUint64(_formatDelegatorStakeKey(g1.address[:]), 100) // previous election

		// call
		_collectOneDelegatorStakeFromEthereum(0)

		// assert
		m.VerifyMocks()
		require.EqualValues(t, 0, state.ReadUint64(_formatDelegatorStakeKey(g1.address[:])))
	})
}

func TestOrbsVotingContract_processVote_collectGuardiansStake_NoState(t *testing.T) {
	guardians := [][20]byte{{0xa1}, {0xa2}}
	InServiceScope(nil, nil, func(m Mockery) {
		_init()
		//prepare
		_setGuardians(guardians)

		// call
		guardians := _getGuardians()
		guardianStakes := _collectGuardiansStake(guardians)

		// assert
		m.VerifyMocks()
		require.Len(t, guardianStakes, 0, "should stay empty")
	})
}

func TestOrbsVotingContract_processVote_collectGuardiansStake_OnlyNumOfGuardiansInState(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)
	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()
		_setNumberOfGuardians(10)

		// call
		guardians := _getGuardians()
		guardianStakes := _collectGuardiansStake(guardians)

		// assert
		m.VerifyMocks()
		require.Len(t, guardianStakes, 0, "should stay empty")
	})
}

func TestOrbsVotingContract_processVote_collectGuardiansStake_GuardiansWithAncientVoteIgnored(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)
	aRecentVoteBlock := h.electionBlock - 1
	anAncientVoteBlock := uint64(10000)

	var v1 = h.addValidator()
	var g1, g2, g3, g4 = h.addGuardian(100), h.addGuardian(200), h.addGuardian(300), h.addGuardian(400)

	g1.vote(aRecentVoteBlock, v1)
	g2.vote(aRecentVoteBlock, v1)
	g3.vote(anAncientVoteBlock, v1)
	g4.vote(0, v1) // fake didn't vote

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()

		// call
		guardians := _getGuardians()
		guardianStakes := _collectGuardiansStake(guardians)

		// assert
		m.VerifyMocks()
		require.Len(t, guardians, 4)
		require.Len(t, guardianStakes, 2)
		_, ok := guardianStakes[g3.address]
		require.False(t, ok, "g3 should not exist ")
		_, ok = guardianStakes[g4.address]
		require.False(t, ok, "g4 should not exist ")
	})
}

func TestOrbsVotingContract_processVote_collectDelegatorStake_DelegatorIgnoredIfIsGuardian(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)
	aRecentVoteBlock := h.electionBlock - 1

	var g1 = h.addGuardian(100)

	g1.vote(aRecentVoteBlock, h.addValidator())

	h.addDelegator(500, g1.address)
	d2 := h.addDelegator(500, g1.address)
	h.addDelegator(500, g1.address)

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()

		// call
		guardians := _getGuardians()
		guardians[d2.address] = true
		delegators, delegatorStakes := _collectDelegatorsStake(guardians)

		// assert
		m.VerifyMocks()
		require.Len(t, delegators, 2)
		require.Len(t, delegatorStakes, 2)
		_, ok := delegatorStakes[d2.address]
		require.False(t, ok, "d2 should not exist as delegator")
	})
}

func TestOrbsVotingContract_processVote_findGuardianDelegators_IgnoreSelfDelegation(t *testing.T) {
	h := newHarnessBlockBased()
	h.electionBlock = uint64(60000)
	h.addDelegator(500, [20]byte{})
	h.delegators[0].delegate = h.delegators[0].address

	InServiceScope(nil, nil, func(m Mockery) {
		_init()

		// prepare
		h.setupOrbsStateBeforeProcessMachine()

		// call
		guardians := _getGuardians()
		delegators, _ := _collectDelegatorsStake(guardians)
		guardianDelegators := _findGuardianDelegators(delegators)

		// assert
		m.VerifyMocks()
		require.Len(t, guardianDelegators, 0)
	})
}

func TestOrbsVotingContract_processVote_calculateOneGuardianVoteRecursive(t *testing.T) {
	guardian := [20]byte{0xa0}
	delegatorStakes := map[[20]byte]uint64{
		{0xb0}: 100,
		{0xb1}: 200,
		{0xb2}: 300,
		{0xb3}: 400,
	}
	tests := []struct {
		name                   string
		expect                 uint64
		relationship           map[[20]byte][][20]byte
		expectParticipantStake map[[20]byte]uint64 // will not include the guardian stake in it.
	}{
		{"simple one delegate", 200, map[[20]byte][][20]byte{{0xa0}: {{0xb1}}}, map[[20]byte]uint64{{0xb1}: 200}},
		{"simple two delegates", 600, map[[20]byte][][20]byte{{0xa0}: {{0xb1}, {0xb3}}}, map[[20]byte]uint64{{0xb3}: 400, {0xb1}: 200}},
		{"simple all delegates", 1000, map[[20]byte][][20]byte{{0xa0}: {{0xb1}, {0xb0}, {0xb2}, {0xb3}}}, map[[20]byte]uint64{{0xb3}: 400, {0xb2}: 300, {0xb1}: 200, {0xb0}: 100}},
		{"level one has another delegate", 500, map[[20]byte][][20]byte{{0xa0}: {{0xb1}}, {0xb1}: {{0xb2}}}, map[[20]byte]uint64{{0xb2}: 300, {0xb1}: 200}},
		{"simple and level one has another delegate", 600, map[[20]byte][][20]byte{{0xa0}: {{0xb0}, {0xb1}}, {0xb1}: {{0xb2}}}, map[[20]byte]uint64{{0xb2}: 300, {0xb1}: 200, {0xb0}: 100}},
		{"level one has another two delegate", 900, map[[20]byte][][20]byte{{0xa0}: {{0xb1}}, {0xb1}: {{0xb2}, {0xb3}}}, map[[20]byte]uint64{{0xb2}: 300, {0xb1}: 200, {0xb3}: 400}},
		{"level two has level one has another two delegate", 1000, map[[20]byte][][20]byte{{0xa0}: {{0xb0}}, {0xb0}: {{0xb1}}, {0xb1}: {{0xb2}, {0xb3}}}, map[[20]byte]uint64{{0xb3}: 400, {0xb2}: 300, {0xb1}: 200, {0xb0}: 100}},
	}
	for i := range tests {
		cTest := tests[i]
		t.Run(cTest.name, func(t *testing.T) {
			var participants [][20]byte
			participantStakes := make(map[[20]byte]uint64)
			stakes := _calculateOneGuardianVoteRecursive(guardian, cTest.relationship, delegatorStakes, &participants, participantStakes)
			require.EqualValues(t, cTest.expect, stakes, fmt.Sprintf("%s was calculated to %d instead of %d", cTest.name, stakes, cTest.expect))
			require.EqualValues(t, len(cTest.expectParticipantStake), len(participantStakes), "participants stake length not equal")
			for k, v := range participantStakes {
				require.EqualValues(t, cTest.expectParticipantStake[k], v, "bad values")
			}
			require.EqualValues(t, len(cTest.expectParticipantStake), len(participants), "participants length not equal")
			for _, p := range participants {
				_, ok := participantStakes[p]
				require.True(t, ok, "missing key")
			}
		})
	}
}

func TestOrbsVotingContract_processVote_guardiansCastVotes(t *testing.T) {
	g0, g1, g2, g3 := [20]byte{0xa0}, [20]byte{0xa1}, [20]byte{0xa2}, [20]byte{0xa3}
	delegatorStakes := map[[20]byte]uint64{
		{0xa0, 0xb0}: 100, {0xa0, 0xb1}: 200,
		{0xa1, 0xb0}: 100, {0xa1, 0xb1}: 200, {0xa1, 0xb2}: 300,
		{0xa2, 0xb0}: 100, {0xa2, 0xb1}: 200, {0xa2, 0xb2}: 300, {0xa2, 0xb3}: 400,
	}
	relationship := map[[20]byte][][20]byte{
		g0: {{0xa0, 0xb0}, {0xa0, 0xb1}},                               // 300
		g1: {{0xa1, 0xb0}, {0xa1, 0xb1}}, {0xa1, 0xb1}: {{0xa1, 0xb2}}, // 600
		g2: {{0xa2, 0xb0}}, {0xa2, 0xb0}: {{0xa2, 0xb1}}, {0xa2, 0xb1}: {{0xa2, 0xb2}, {0xa2, 0xb3}}, // 1000
	}
	v1, v2, v3, v4, v5 := [20]byte{0xc1}, [20]byte{0xc2}, [20]byte{0xc3}, [20]byte{0xc4}, [20]byte{0xc5}
	g0Vote := [][20]byte{v1, v2}
	g1Vote := [][20]byte{v3, v4, v5}
	g2Vote := [][20]byte{v1, v3, v5}
	g3Vote := make([][20]byte, 0) // voted for nonec

	InServiceScope(nil, nil, func(m Mockery) {
		_init()
		_setCandidates(g0[:], g0Vote)
		_setCandidates(g1[:], g1Vote)
		_setCandidates(g2[:], g2Vote)
		_setCandidates(g3[:], g3Vote)
		_setNumberOfGuardians(4)
		_setGuardianAtIndex(0, g0[:])
		_setGuardianAtIndex(1, g1[:])
		_setGuardianAtIndex(2, g2[:])
		_setGuardianAtIndex(3, g3[:])

		tests := []struct {
			name          string
			expect        map[[20]byte]uint64
			expectedTotal uint64
			guardianStake map[[20]byte]uint64
		}{
			{"simple one guardian", map[[20]byte]uint64{v1: 320, v2: 320}, 320, map[[20]byte]uint64{g0: 20}},
			{"simple two guardian", map[[20]byte]uint64{v1: 320, v2: 320, v3: 700, v4: 700, v5: 700}, 1020, map[[20]byte]uint64{g0: 20, g1: 100}},
			{"simple three guardian", map[[20]byte]uint64{v1: 1330, v2: 320, v3: 1710, v4: 700, v5: 1710}, 2030, map[[20]byte]uint64{g0: 20, g1: 100, g2: 10}},
			{"simple second guardian no delegates", map[[20]byte]uint64{v1: 320, v2: 320}, 370, map[[20]byte]uint64{g0: 20, g3: 50}},
		}
		for i := range tests {
			cTest := tests[i]
			candidatesVotes, total, _, _, _ := _guardiansCastVotes(cTest.guardianStake, relationship, delegatorStakes)
			require.EqualValues(t, cTest.expectedTotal, total)
			for validator, vote := range cTest.expect {
				require.EqualValues(t, vote, candidatesVotes[validator])
			}
		}
	})
}

func TestOrbsVotingContract_processVote_processValidatorsSelection(t *testing.T) {
	v1, v2, v3, v4, v5 := [20]byte{0xc1}, [20]byte{0xc2}, [20]byte{0xc3}, [20]byte{0xc4}, [20]byte{0xc5}

	tests := []struct {
		name     string
		expect   [][20]byte
		original map[[20]byte]uint64
		maxVotes uint64
	}{
		{"all pass", [][20]byte{v1, v2, v3, v4}, map[[20]byte]uint64{v1: 320, v2: 200, v3: 400, v4: 500}, 1000},
		{"one voted out", [][20]byte{v1, v3, v4}, map[[20]byte]uint64{v1: 320, v2: 701, v3: 400, v4: 699}, 1000},
		{"non valid also voted out", [][20]byte{v1, v3, v4}, map[[20]byte]uint64{v1: 320, v2: 701, v3: 400, v4: 699, v5: 400}, 1000},
	}
	InServiceScope(nil, nil, func(m Mockery) {
		MIN_ELECTED_VALIDATORS = 2
		_init()
		_setNumberOfValidators(4)
		_setValidatorEthereumAddressAtIndex(0, v1[:])
		_setValidatorEthereumAddressAtIndex(1, v2[:])
		_setValidatorEthereumAddressAtIndex(2, v3[:])
		_setValidatorEthereumAddressAtIndex(3, v4[:])

		for i := range tests {
			cTest := tests[i]
			validCandidates := _processValidatorsSelection(cTest.original, cTest.maxVotes)
			require.Equal(t, len(cTest.expect), len(validCandidates))
			require.ElementsMatch(t, cTest.expect, validCandidates)
		}
	})
}

repository: orbs-network/orbs-network-go

repo_name: orbs-network/orbs-network-go

gha_license_id: NOASSERTION


text:
set(NODE_TOOLS "${CMAKE_SOURCE_DIR}/node_modules/script.cmake")
if(NOT EXISTS ${NODE_TOOLS})
execute_process(COMMAND cmd /c npm install WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
endif()
include(${NODE_TOOLS}/index.cmake)

license: MIT

license_type: permissive

branch_name: refs/heads/main

extension: cmake


text:
package auth

import (
	"net/http"
	"strings"

	"github.com/auth0-community/go-auth0"
	"gopkg.in/square/go-jose.v2"
)

// Auth0 contains dependencies for the Auth0 handler
type Auth0 struct {
	Auth
	c Auth0Config
}

// Auth0Config contains configuration options for Auth0 handler
type Auth0Config struct {
	Secret   []byte
	Audience []string
	Domain   string
}

// NewAuth0 returns a new Auth struct
func NewAuth0(l Logger, c Auth0Config) *Auth0 {
	return &Auth0{Auth{l: l}, c}
}

type claims struct {
	Issuer  string `json:"iss"`
	Subject string `json:"sub"`
	Scope   string `json:"scope"`
}

// Authenticate authenticates a request and calls the next handler
func (a *Auth0) Authenticate(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		secretProvider := auth0.NewKeyProvider(a.c.Secret)
		configuration := auth0.NewConfiguration(secretProvider, a.c.Audience, "https://"+a.c.Domain+"/", jose.HS256)
		validator := auth0.NewValidator(configuration, nil)

		token, err := validator.ValidateRequest(r)

		if err != nil {
			a.l.Printf("Error parsing token: %v", err)
			a.l.Printf("Token is not valid: %v", token)
			if a.f != nil {
				a.f.WriteResponse(w, a.f.Error("Unauthorized"), http.StatusUnauthorized)
			} else {
				w.WriteHeader(http.StatusUnauthorized)
				w.Write([]byte("Unauthorized"))
			}
			return
		}
		c := claims{}
		validator.Claims(r, token, &c)
		ps := getDefaultPerms(&c)

		next.ServeHTTP(ResponseContext{w, Context{c.Issuer, c.Subject, ps}}, r)
	})
}

func getDefaultPerms(c *claims) []Permission {
	scopes := strings.Split(c.Scope, " ")
	for _, scope := range scopes {
		switch scope {
		case "type:anon":
			return []Permission{PermNone}
		}
	}
	return GetDefaultUserPerms()
}

branch_name: refs/heads/master

gha_license_id: MIT

gha_language: Go

extension: go


text:
@INPROCEEDINGS{Pulo2003,
  author = {Kevin Pulo and Masahiro Takatsuko},
  title = {Inclusion Tree Layout Convention: An Empirical Investigation},
  pages = {27--37},
  abstract = {The inclusion tree layout convention involves drawing trees as nested rectangles rather than the more common node-link diagrams. Finding good inclusion layouts presents some unique challenges, for example, the quantification of what is meant by the "size" of a rectangle. This paper empirically evaluates and investigates several rectangle size measures for their usefulness in the inclusion tree layout convention. We find that the area size measure, commonly used in graph drawing, is very poorly suited to the inclusion layout convention, whilst size measures based on the aspect ratio of the layout are more appropriate and give better results.},
  url = {http://portal.acm.org/citation.cfm?id=857084},
  year = {2003},
  booktitle = {APVIS'03: Proceedings of the Asia Pacific Symposium on Information Visualization},
  editor = {Tim Pattison and Bruce Thomas},
  publisher = {Australian Computer Society},
  series = {Conference in Research and Practice in Information Technology},
  isbn = {1920682031}
}

repository: vis-au/treevisnet

repo_name: vis-au/treevisnet

gha_language: TeX

extension: bib


text:
# (c) https://github.com/dev-cafe/autocmake/blob/master/AUTHORS.md
# licensed under BSD-3: https://github.com/dev-cafe/autocmake/blob/master/LICENSE

#.rst:
#
# Sets binary and library output directories to ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}
# and ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}, respectively.
#
# Variables modified::
#
#   CMAKE_ARCHIVE_OUTPUT_DIRECTORY
#   CMAKE_LIBRARY_OUTPUT_DIRECTORY
#   CMAKE_RUNTIME_OUTPUT_DIRECTORY

include(GNUInstallDirs)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})

repository: dev-cafe/autocmake

repo_name: dev-cafe/autocmake

gha_language: CMake


text:
@inproceedings{kroer2018solving,
 author = {Christian Kroer and Gabriele Farina and Tuomas Sandholm},
 booktitle = {NeurIPS (spotlight presentation)},
 title = {Solving Large Sequential Games with the Excessive Gap Technique},
 url = {https://arxiv.org/abs/1810.03063},
 year = {2018}
}

repository: ChrKroer/academic-kickstart

repo_name: ChrKroer/academic-kickstart


text:
package kubernetes

import (
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"os/signal"
	"path/filepath"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"syscall"
	"time"

	log "github.com/sirupsen/logrus"
	"github.com/zalando/skipper/eskip"
	"github.com/zalando/skipper/filters/builtin"
	"github.com/zalando/skipper/predicates/source"
	"github.com/zalando/skipper/predicates/traffic"
)

const (
	defaultKubernetesURL               = "http://localhost:8001"
	ingressesClusterURI                = "/apis/extensions/v1beta1/ingresses"
	ingressesNamespaceFmt              = "/apis/extensions/v1beta1/namespaces/%s/ingresses"
	ingressClassKey                    = "kubernetes.io/ingress.class"
	defaultIngressClass                = "skipper"
	defaultLoadbalancerAlgorithm       = "roundRobin"
	ingressRouteIDPrefix               = "kube"
	defaultEastWestDomainRegexpPostfix = "[.]skipper[.]cluster[.]local"
	endpointsClusterURI                = "/api/v1/endpoints"
	endpointsNamespaceFmt              = "/api/v1/namespaces/%s/endpoints"
	servicesClusterURI                 = "/api/v1/services"
	servicesNamespaceFmt               = "/api/v1/namespaces/%s/services"
	serviceAccountDir                  = "/var/run/secrets/kubernetes.io/serviceaccount/"
	serviceAccountTokenKey             = "token"
	serviceAccountRootCAKey            = "ca.crt"
	serviceHostEnvVar                  = "KUBERNETES_SERVICE_HOST"
	servicePortEnvVar                  = "KUBERNETES_SERVICE_PORT"
	healthcheckRouteID                 = "kube__healthz"
	httpRedirectRouteID                = "kube__redirect"
	healthcheckPath                    = "/kube-system/healthz"
	backendWeightsAnnotationKey        = "zalando.org/backend-weights"
	ratelimitAnnotationKey             = "zalando.org/ratelimit"
	skipperfilterAnnotationKey         = "zalando.org/skipper-filter"
	skipperpredicateAnnotationKey      = "zalando.org/skipper-predicate"
	skipperRoutesAnnotationKey         = "zalando.org/skipper-routes"
	skipperLoadbalancerAnnotationKey   = "zalando.org/skipper-loadbalancer"
	pathModeAnnotationKey              = "zalando.org/skipper-ingress-path-mode"
)

// PathMode values are used to control the ingress path interpretation. The path mode can
// be set globally for all ingress paths, and it can be overruled by the individual ingress
// rules using the zalando.org/skipper-ingress-path-mode annotation. When path mode is not
// set, the Kubernetes ingress specification is used, accepting regular expressions with a
// mandatory leading "/", automatically prepended by the "^" control character.
//
// When PathPrefix is used, the path matching becomes deterministic when
// a request could match more than one ingress routes otherwise.
type PathMode int

const (
	// KubernetesIngressMode is the default path mode. Expects regular expressions
	// with a mandatory leading "/". The expressions are automatically prepended by
	// the "^" control character.
	KubernetesIngressMode PathMode = iota

	// PathRegexp is like KubernetesIngressMode but is not prepended by the "^"
	// control character.
	PathRegexp

	// PathPrefix is like the PathSubtree predicate. E.g. "/foo/bar" will match
	// "/foo/bar" or "/foo/bar/baz", but won't match "/foo/barooz".
	//
	// In this mode, when a Path or a PathSubtree predicate is set in an annotation,
	// the value from the annotation has precedence over the standard ingress path.
	PathPrefix
)

const (
	kubernetesIngressModeString = "kubernetes-ingress"
	pathRegexpString            = "path-regexp"
	pathPrefixString            = "path-prefix"
)

const maxFileSize = 1024 * 1024 // 1MB

var internalIPs = []interface{}{
	"10.0.0.0/8",
	"192.168.0.0/16",
	"172.16.0.0/12",
	"127.0.0.1/8",
	"fd00::/8",
	"::1/128",
}

// Options is used to initialize the Kubernetes DataClient.
type Options struct {
	// KubernetesInCluster defines if skipper is deployed and running in the kubernetes cluster
	// this would make authentication with API server happen through the service account, rather than
	// running along side kubectl proxy
	KubernetesInCluster bool

	// KubernetesURL is used as the base URL for Kubernetes API requests. Defaults to http://localhost:8001.
	// (TBD: support in-cluster operation by taking the address and certificate from the standard Kubernetes
	// environment variables.)
	KubernetesURL string

	// KubernetesNamespace is used to switch between finding ingresses in the cluster-scope or limit
	// the ingresses to only those in the specified namespace. Defaults to "" which means monitor ingresses
	// in the cluster-scope.
	KubernetesNamespace string

	// KubernetesEnableEastWest if set adds automatically routes
	// with "%s.%s.skipper.cluster.local" domain pattern
	KubernetesEnableEastWest bool

	// ProvideHealthcheck, when set, tells the data client to append a healthcheck route to the ingress
	// routes in case of successfully receiving the ingress items from the API (even if individual ingress
	// items may be invalid), or a failing healthcheck route when the API communication fails. The
	// healthcheck endpoint can be accessed from internal IPs on any hostname, with the path
	// /kube-system/healthz.
	//
	// When used in a custom configuration, the current filter registry needs to include the status()
	// filter, and the available predicates need to include the Source() predicate.
	ProvideHealthcheck bool

	// ProvideHTTPSRedirect, when set, tells the data client to append an HTTPS redirect route to the
	// ingress routes. This route will detect the X-Forwarded-Proto=http and respond with a 301 message
	// to the HTTPS equivalent of the same request (using the redirectTo(301, "https:") filter). The
	// X-Forwarded-Proto and X-Forwarded-Port is expected to be set by the load balancer.
	//
	// (See also https://github.com/zalando-incubator/kube-ingress-aws-controller as part of the
	// https://github.com/zalando-incubator/kubernetes-on-aws project.)
	ProvideHTTPSRedirect bool

	// HTTPSRedirectCode, when set defines which redirect code to use for redirecting from HTTP to HTTPS.
	// By default, 308 StatusPermanentRedirect is used.
	HTTPSRedirectCode int

	// IngressClass is a regular expression to filter only those ingresses that match. If an ingress does
	// not have a class annotation or the annotation is an empty string, skipper will load it. The default
	// value for the ingress class is 'skipper'.
	//
	// For further information see:
	//		https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/multiple-ingress-controllers
	IngressClass string

	// ReverseSourcePredicate set to true will do the Source IP
	// whitelisting for the heartbeat endpoint correctly in AWS.
	// Amazon's ALB writes the client IP to the last item of the
	// string list of the X-Forwarded-For header, in this case you
	// want to set this to true.
	ReverseSourcePredicate bool

	// Noop, WIP.
	ForceFullUpdatePeriod time.Duration

	// WhitelistedHealthcheckCIDR to be appended to the default iprange
	WhitelistedHealthCheckCIDR []string

	// PathMode controls the default interpretation of ingress paths in cases when the ingress doesn't
	// specify it with an annotation.
	PathMode PathMode

	// KubernetesEastWestDomain sets the DNS domain to be used for east west traffic, defaults to "skipper.cluster.local"
	KubernetesEastWestDomain string

	// DefaultFiltersDir enables default filters mechanism and sets the location of the default filters.
	// The provided filters are then applied to all routes.
	DefaultFiltersDir string
}

// Client is a Skipper DataClient implementation used to create routes based on Kubernetes Ingress settings.
type Client struct {
	httpClient                  *http.Client
	provideHealthcheck          bool
	healthy                     bool
	provideHTTPSRedirect        bool
	termReceived                bool
	reverseSourcePredicate      bool
	kubernetesEnableEastWest    bool
	httpsRedirectCode           int
	apiURL                      string
	token                       string
	eastWestDomainRegexpPostfix string
	ingressesURI                string
	servicesURI                 string
	endpointsURI                string
	current                     map[string]*eskip.Route
	sigs                        chan os.Signal
	ingressClass                *regexp.Regexp
	pathMode                    PathMode
	quit                        chan struct{}
	defaultFiltersDir           string
}

var (
	nonWord = regexp.MustCompile(`\W`)

	errServiceNotFound      = errors.New("service not found")
	errEndpointNotFound     = errors.New("endpoint not found")
	errAPIServerURLNotFound = errors.New("kubernetes API server URL could not be constructed from env vars")
	errInvalidCertificate   = errors.New("invalid CA")
)

// New creates and initializes a Kubernetes DataClient.
func New(o Options) (*Client, error) {
	quit := make(chan struct{})
	httpClient, err := buildHTTPClient(serviceAccountDir+serviceAccountRootCAKey, o.KubernetesInCluster, quit)
	if err != nil {
		return nil, err
	}

	apiURL, err := buildAPIURL(o)
	if err != nil {
		return nil, err
	}

	token, err := readServiceAccountToken(serviceAccountDir+serviceAccountTokenKey, o.KubernetesInCluster)
	if err != nil {
		return nil, err
	}

	ingCls := defaultIngressClass
	if o.IngressClass != "" {
		ingCls = o.IngressClass
	}

	ingClsRx, err := regexp.Compile(ingCls)
	if err != nil {
		return nil, err
	}

	log.Debugf(
		"running in-cluster: %t. api server url: %s. provide health check: %t. ingress.class filter: %s. namespace: %s",
		o.KubernetesInCluster, apiURL, o.ProvideHealthcheck, ingCls, o.KubernetesNamespace,
	)

	var sigs chan os.Signal
	if o.ProvideHealthcheck {
		log.Info("register sigterm handler")
		sigs = make(chan os.Signal, 1)
		signal.Notify(sigs, syscall.SIGTERM)
	}

	if len(o.WhitelistedHealthCheckCIDR) > 0 {
		whitelistCIDRS := make([]interface{}, len(o.WhitelistedHealthCheckCIDR))
		for i, v := range o.WhitelistedHealthCheckCIDR {
			whitelistCIDRS[i] = v
		}
		internalIPs = append(internalIPs, whitelistCIDRS...)
		log.Debugf("new internal ips are: %s", internalIPs)
	}

	httpsRedirectCode := http.StatusPermanentRedirect
	if o.HTTPSRedirectCode != 0 {
		httpsRedirectCode = o.HTTPSRedirectCode
	}

	eastWestDomainRegexpPostfix := defaultEastWestDomainRegexpPostfix
	if o.KubernetesEastWestDomain != "" {
		if strings.HasPrefix(o.KubernetesEastWestDomain, ".") {
			o.KubernetesEastWestDomain = o.KubernetesEastWestDomain[1:len(o.KubernetesEastWestDomain)]
		}
		if strings.HasSuffix(o.KubernetesEastWestDomain, ".") {
			o.KubernetesEastWestDomain = o.KubernetesEastWestDomain[:len(o.KubernetesEastWestDomain)-1]
		}
		eastWestDomainRegexpPostfix = "[.]" + strings.Replace(o.KubernetesEastWestDomain, ".", "[.]", -1)
	}

	result := &Client{
		httpClient:                  httpClient,
		apiURL:                      apiURL,
		provideHealthcheck:          o.ProvideHealthcheck,
		provideHTTPSRedirect:        o.ProvideHTTPSRedirect,
		httpsRedirectCode:           httpsRedirectCode,
		current:                     make(map[string]*eskip.Route),
		token:                       token,
		sigs:                        sigs,
		ingressClass:                ingClsRx,
		reverseSourcePredicate:      o.ReverseSourcePredicate,
		pathMode:                    o.PathMode,
		quit:                        quit,
		kubernetesEnableEastWest:    o.KubernetesEnableEastWest,
		eastWestDomainRegexpPostfix: eastWestDomainRegexpPostfix,
		ingressesURI:                ingressesClusterURI,
		servicesURI:                 servicesClusterURI,
		endpointsURI:                endpointsClusterURI,
		defaultFiltersDir:           o.DefaultFiltersDir,
	}
	if o.KubernetesNamespace != "" {
		result.setNamespace(o.KubernetesNamespace)
	}
	return result, nil
}

func (c *Client) setNamespace(namespace string) {
	c.ingressesURI = fmt.Sprintf(ingressesNamespaceFmt, namespace)
	c.servicesURI = fmt.Sprintf(servicesNamespaceFmt, namespace)
	c.endpointsURI = fmt.Sprintf(endpointsNamespaceFmt, namespace)
}

// String returns the string representation of the path mode, the same
// values that are used in the path mode annotation.
func (m PathMode) String() string {
	switch m {
	case PathRegexp:
		return pathRegexpString
	case PathPrefix:
		return pathPrefixString
	default:
		return kubernetesIngressModeString
	}
}

// ParsePathMode parses the string representations of the different
// path modes.
func ParsePathMode(s string) (PathMode, error) {
	switch s {
	case kubernetesIngressModeString:
		return KubernetesIngressMode, nil
	case pathRegexpString:
		return PathRegexp, nil
	case pathPrefixString:
		return PathPrefix, nil
	default:
		return 0, fmt.Errorf("invalid path mode string: %s", s)
	}
}

func readServiceAccountToken(tokenFilePath string, inCluster bool) (string, error) {
	if !inCluster {
		return "", nil
	}

	bToken, err := ioutil.ReadFile(tokenFilePath)
	if err != nil {
		return "", err
	}

	return string(bToken), nil
}

func buildHTTPClient(certFilePath string, inCluster bool, quit chan struct{}) (*http.Client, error) {
	if !inCluster {
		return http.DefaultClient, nil
	}

	rootCA, err := ioutil.ReadFile(certFilePath)
	if err != nil {
		return nil, err
	}
	certPool := x509.NewCertPool()
	if !certPool.AppendCertsFromPEM(rootCA) {
		return nil, errInvalidCertificate
	}

	transport := &http.Transport{
		DialContext: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 30 * time.Second,
			DualStack: true,
		}).DialContext,
		TLSHandshakeTimeout:   10 * time.Second,
		ResponseHeaderTimeout: 10 * time.Second,
		ExpectContinueTimeout: 30 * time.Second,
		MaxIdleConns:          5,
		MaxIdleConnsPerHost:   5,
		TLSClientConfig: &tls.Config{
			MinVersion: tls.VersionTLS12,
			RootCAs:    certPool,
		},
	}

	// regularly force closing idle connections
	go func() {
		for {
			select {
			case <-time.After(10 * time.Second):
				transport.CloseIdleConnections()
			case <-quit:
				return
			}
		}
	}()

	return &http.Client{
		Transport: transport,
	}, nil
}

func buildAPIURL(o Options) (string, error) {
	if !o.KubernetesInCluster {
		if o.KubernetesURL == "" {
			return defaultKubernetesURL, nil
		}
		return o.KubernetesURL, nil
	}

	host, port := os.Getenv(serviceHostEnvVar), os.Getenv(servicePortEnvVar)
	if host == "" || port == "" {
		return "", errAPIServerURLNotFound
	}

	return "https://" + net.JoinHostPort(host, port), nil
}

func (c *Client) createRequest(method, url string, body io.Reader) (*http.Request, error) {
	req, err := http.NewRequest(method, url, body)
	if err != nil {
		return nil, err
	}

	if c.token != "" {
		req.Header.Set("Authorization", "Bearer "+c.token)
	}

	return req, nil
}

func (c *Client) getJSON(uri string, a interface{}) error {
	url := c.apiURL + uri
	log.Debugf("making request to: %s", url)

	req, err := c.createRequest("GET", url, nil)
	if err != nil {
		return err
	}

	rsp, err := c.httpClient.Do(req)
	if err != nil {
		log.Debugf("request to %s failed: %v", url, err)
		return err
	}

	log.Debugf("request to %s succeeded", url)
	defer rsp.Body.Close()

	if rsp.StatusCode == http.StatusNotFound {
		return errServiceNotFound
	}

	if rsp.StatusCode != http.StatusOK {
		log.Debugf("request failed, status: %d, %s", rsp.StatusCode, rsp.Status)
		return fmt.Errorf("request failed, status: %d, %s", rsp.StatusCode, rsp.Status)
	}

	b := bytes.NewBuffer(nil)
	if _, err = io.Copy(b, rsp.Body); err != nil {
		log.Debugf("reading response body failed: %v", err)
		return err
	}

	err = json.Unmarshal(b.Bytes(), a)
	if err != nil {
		log.Debugf("invalid response format: %v", err)
	}

	return err
}

func (c *Client) getServiceURL(svc *service, port backendPort) (string, error) {
	if p, ok := port.number(); ok {
		log.Debugf("service port as number: %d", p)
		return fmt.Sprintf("http://%s:%d", svc.Spec.ClusterIP, p), nil
	}

	pn, _ := port.name()
	for _, pi := range svc.Spec.Ports {
		if pi.Name == pn {
			log.Debugf("service port found by name: %s -> %d", pn, pi.Port)
			return fmt.Sprintf("http://%s:%d", svc.Spec.ClusterIP, pi.Port), nil
		}
	}

	log.Debugf("service port not found by name: %s", pn)
	return "", errServiceNotFound
}

// TODO: find a nicer way to autogenerate route IDs
func routeID(namespace, name, host, path, backend string) string {
	namespace = nonWord.ReplaceAllString(namespace, "_")
	name = nonWord.ReplaceAllString(name, "_")
	host = nonWord.ReplaceAllString(host, "_")
	path = nonWord.ReplaceAllString(path, "_")
	backend = nonWord.ReplaceAllString(backend, "_")
	return fmt.Sprintf("%s_%s__%s__%s__%s__%s", ingressRouteIDPrefix, namespace, name, host, path, backend)
}

// routeIDForCustom generates a route id for a custom route of an ingress
// resource.
func routeIDForCustom(namespace, name, id, host string, index int) string {
	name = name + "_" + id + "_" + strconv.Itoa(index)
	return routeID(namespace, name, host, "", "")
}

func patchRouteID(rid string) string {
	return "kubeew" + rid[len(ingressRouteIDPrefix):]
}

func getLoadBalancerAlgorithm(m *metadata) string {
	algorithm := defaultLoadbalancerAlgorithm
	if algorithmAnnotationValue, ok := m.Annotations[skipperLoadbalancerAnnotationKey]; ok {
		algorithm = algorithmAnnotationValue
	}

	return algorithm
}

// converts the default backend if any
func (c *Client) convertDefaultBackend(state *clusterState, i *ingressItem) (*eskip.Route, bool, error) {
	// the usage of the default backend depends on what we want
	// we can generate a hostname out of it based on shared rules
	// and instructions in annotations, if there are no rules defined

	// this is a flaw in the ingress API design, because it is not on the hosts' level, but the spec
	// tells to match if no rule matches. This means that there is no matching rule on this ingress
	// and if there are multiple ingress items, then there is a race between them.
	if i.Spec.DefaultBackend == nil {
		return nil, false, nil
	}

	var (
		eps     []string
		err     error
		ns      = i.Metadata.Namespace
		name    = i.Metadata.Name
		svcName = i.Spec.DefaultBackend.ServiceName
		svcPort = i.Spec.DefaultBackend.ServicePort
	)

	svc, err := state.getService(ns, svcName)
	if err != nil {
		log.Errorf("convertDefaultBackend: Failed to get service %s, %s, %s", ns, svcName, svcPort)
		return nil, false, err
	}

	targetPort, err := svc.GetTargetPort(svcPort)
	if err != nil {
		err = nil
		log.Errorf("Failed to find target port %v, %s, fallback to service", svc.Spec.Ports, svcPort)
	} else if svc.Spec.Type == "ExternalName" {
		scheme := "https"
		if targetPort != "443" {
			scheme = "http"
		}
		u := fmt.Sprintf("%s://%s:%s", scheme, svc.Spec.ExternalName, targetPort)
		f, err := eskip.ParseFilters(fmt.Sprintf(`setRequestHeader("Host", "%s")`, svc.Spec.ExternalName))
		if err != nil {
			return nil, false, err
		}
		return &eskip.Route{
			Id:          routeID(ns, name, "default", "", svc.Spec.ExternalName),
			BackendType: eskip.NetworkBackend,
			Backend:     u,
			Filters:     f,
		}, true, nil
	} else {
		// TODO(aryszka): check docs that service name is always good for requesting the endpoints
		log.Debugf("Found target port %v, for service %s", targetPort, svcName)
		eps, err = state.getEndpoints(
			ns,
			svcName,
			svcPort.String(),
			targetPort,
		)
		log.Debugf("convertDefaultBackend: Found %d endpoints for %s: %v", len(eps), svcName, err)
	}

	if len(eps) == 0 || err == errEndpointNotFound {

		address, err2 := c.getServiceURL(svc, svcPort)
		if err2 != nil {
			return nil, false, err2
		}

		return &eskip.Route{
			Id:      routeID(ns, name, "", "", ""),
			Backend: address,
		}, true, nil
	} else if len(eps) == 1 {
		return &eskip.Route{
			Id:      routeID(ns, name, "", "", ""),
			Backend: eps[0],
		}, true, nil
	} else if err != nil {
		return nil, false, err
	}

	return &eskip.Route{
		Id:          routeID(ns, name, "", "", ""),
		BackendType: eskip.LBBackend,
		LBEndpoints: eps,
		LBAlgorithm: getLoadBalancerAlgorithm(i.Metadata),
	}, true, nil
}

func setPath(m PathMode, r *eskip.Route, p string) {
	if p == "" {
		return
	}

	switch m {
	case PathPrefix:
		r.Predicates = append(r.Predicates, &eskip.Predicate{
			Name: "PathSubtree",
			Args: []interface{}{p},
		})
	case PathRegexp:
		r.PathRegexps = []string{p}
	default:
		r.PathRegexps = []string{"^" + p}
	}
}

func (c *Client) convertPathRule(
	state *clusterState,
	metadata *metadata,
	host string,
	prule *pathRule,
	pathMode PathMode,
) (*eskip.Route, error) {

	ns := metadata.Namespace
	name := metadata.Name

	if prule.Backend == nil {
		return nil, fmt.Errorf("invalid path rule, missing backend in: %s/%s/%s", ns, name, host)
	}

	var (
		eps []string
		err error
		svc *service
	)

	var hostRegexp []string
	if host != "" {
		hostRegexp = []string{"^" + strings.Replace(host, ".", "[.]", -1) + "$"}
	}
	svcPort := prule.Backend.ServicePort
	svcName := prule.Backend.ServiceName

	svc, err = state.getService(ns, svcName)
	if err != nil {
		log.Errorf("convertPathRule: Failed to get service %s, %s, %s", ns, svcName, svcPort)
		return nil, err
	}

	targetPort, err := svc.GetTargetPort(svcPort)
	if err != nil {
		// fallback to service, but service definition is wrong or no pods
		log.Debugf("Failed to find target port for service %s, fallback to service: %v", svcName, err)
		err = nil
	} else if svc.Spec.Type == "ExternalName" {
		scheme := "https"
		if targetPort != "443" {
			scheme = "http"
		}
		u := fmt.Sprintf("%s://%s:%s", scheme, svc.Spec.ExternalName, targetPort)
		f, e := eskip.ParseFilters(fmt.Sprintf(`setRequestHeader("Host", "%s")`, svc.Spec.ExternalName))
		if e != nil {
			return nil, e
		}
		return &eskip.Route{
			Id:          routeID(ns, name, "", "", svc.Spec.ExternalName),
			BackendType: eskip.NetworkBackend,
			Backend:     u,
			Filters:     f,
		}, nil
	} else {
		// err handled below
		eps, err = state.getEndpoints(ns, svcName, svcPort.String(), targetPort)
		log.Debugf("convertPathRule: Found %d endpoints %s for %s", len(eps), targetPort, svcName)
	}

	if len(eps) == 0 || err == errEndpointNotFound {

		address, err2 := c.getServiceURL(svc, svcPort)
		if err2 != nil {
			return nil, err2
		}
		r := &eskip.Route{
			Id:          routeID(ns, name, host, prule.Path, svcName),
			Backend:     address,
			HostRegexps: hostRegexp,
		}

		setPath(pathMode, r, prule.Path)

		if 0.0 < prule.Backend.Traffic && prule.Backend.Traffic < 1.0 {
			r.Predicates = append([]*eskip.Predicate{{
				Name: traffic.PredicateName,
				Args: []interface{}{prule.Backend.Traffic},
			}}, r.Predicates...)
			log.Debugf("Traffic weight %.2f for backend '%s'", prule.Backend.Traffic, svcName)
		}
		return r, nil

	} else if err != nil {
		return nil, err
	}
	log.Debugf("%d routes for %s/%s/%s", len(eps), ns, svcName, svcPort)

	if len(eps) == 1 {
		r := &eskip.Route{
			Id:          routeID(ns, name, host, prule.Path, svcName),
			Backend:     eps[0],
			HostRegexps: hostRegexp,
		}

		setPath(pathMode, r, prule.Path)

		// add traffic predicate if traffic weight is between 0.0 and 1.0
		if 0.0 < prule.Backend.Traffic && prule.Backend.Traffic < 1.0 {
			r.Predicates = append([]*eskip.Predicate{{
				Name: traffic.PredicateName,
				Args: []interface{}{prule.Backend.Traffic},
			}}, r.Predicates...)
			log.Debugf("Traffic weight %.2f for backend '%s'", prule.Backend.Traffic, svcName)
		}
		return r, nil
	}

	if len(eps) == 0 {
		return nil, nil
	}

	r := &eskip.Route{
		Id:          routeID(ns, name, host, prule.Path, prule.Backend.ServiceName),
		BackendType: eskip.LBBackend,
		LBEndpoints: eps,
		LBAlgorithm: getLoadBalancerAlgorithm(metadata),
		HostRegexps: hostRegexp,
	}
	setPath(pathMode, r, prule.Path)

	// add traffic predicate if traffic weight is between 0.0 and 1.0
	if 0.0 < prule.Backend.Traffic && prule.Backend.Traffic < 1.0 {
		r.Predicates = append([]*eskip.Predicate{{
			Name: traffic.PredicateName,
			Args: []interface{}{prule.Backend.Traffic},
		}}, r.Predicates...)
		log.Debugf("Traffic weight %.2f for backend '%s'", prule.Backend.Traffic, svcName)
	}

	return r, nil
}

func applyAnnotationPredicates(m PathMode, r *eskip.Route, annotation string) error {
	if annotation == "" {
		return nil
	}

	predicates, err := eskip.ParsePredicates(annotation)
	if err != nil {
		return err
	}

	// to avoid conflict, give precedence for those predicates that come
	// from annotations
	if m == PathPrefix {
		for _, p := range predicates {
			if p.Name != "Path" && p.Name != "PathSubtree" {
				continue
			}

			r.Path = ""
			for i, p := range r.Predicates {
				if p.Name != "PathSubtree" && p.Name != "Path" {
					continue
				}

				copy(r.Predicates[i:], r.Predicates[i+1:])
				r.Predicates[len(r.Predicates)-1] = nil
				r.Predicates = r.Predicates[:len(r.Predicates)-1]
				break
			}
		}
	}

	r.Predicates = append(r.Predicates, predicates...)
	return nil
}

// ingressToRoutes logs if an invalid found, but proceeds with the
// valid ones.  Reporting failures in Ingress status is not possible,
// because Ingress status field is v1.LoadBalancerIngress that only
// supports IP and Hostname as string.
func (c *Client) ingressToRoutes(state *clusterState, defaultFilters map[resourceId]string) ([]*eskip.Route, error) {
	routes := make([]*eskip.Route, 0, len(state.ingresses))
	hostRoutes := make(map[string][]*eskip.Route)
	redirect := createRedirectInfo(c.provideHTTPSRedirect, c.httpsRedirectCode)
	for _, i := range state.ingresses {
		if i.Metadata == nil || i.Metadata.Namespace == "" || i.Metadata.Name == "" ||
			i.Spec == nil {
			log.Error("invalid ingress item: missing metadata")
			continue
		}

		logger := log.WithFields(log.Fields{
			"ingress": fmt.Sprintf("%s/%s", i.Metadata.Namespace, i.Metadata.Name),
		})

		redirect.initCurrent(i.Metadata)

		if r, ok, err := c.convertDefaultBackend(state, i); ok {
			routes = append(routes, r)
		} else if err != nil {
			logger.Errorf("error while converting default backend: %v", err)
		}

		// parse filter and ratelimit annotation
		var annotationFilter string
		if ratelimitAnnotationValue, ok := i.Metadata.Annotations[ratelimitAnnotationKey]; ok {
			annotationFilter = ratelimitAnnotationValue
		}
		if val, ok := i.Metadata.Annotations[skipperfilterAnnotationKey]; ok {
			if annotationFilter != "" {
				annotationFilter += " -> "
			}
			annotationFilter += val
		}

		// parse predicate annotation
		var annotationPredicate string
		if val, ok := i.Metadata.Annotations[skipperpredicateAnnotationKey]; ok {
			annotationPredicate = val
		}

		// parse routes annotation
		var extraRoutes []*eskip.Route
		annotationRoutes := i.Metadata.Annotations[skipperRoutesAnnotationKey]
		if annotationRoutes != "" {
			var err error
			extraRoutes, err = eskip.Parse(annotationRoutes)
			if err != nil {
				logger.Errorf("failed to parse routes from %s, skipping: %v", skipperRoutesAnnotationKey, err)
			}
		}

		// parse backend-weights annotation if it exists
		var backendWeights map[string]float64
		if backends, ok := i.Metadata.Annotations[backendWeightsAnnotationKey]; ok {
			err := json.Unmarshal([]byte(backends), &backendWeights)
			if err != nil {
				logger.Errorf("error while parsing backend-weights annotation: %v", err)
			}
		}

		// parse pathmode from annotation or fallback to global default
		pathMode := c.pathMode
		if pathModeString, ok := i.Metadata.Annotations[pathModeAnnotationKey]; ok {
			if p, err := ParsePathMode(pathModeString); err != nil {
				log.Errorf("Failed to get path mode for ingress %s/%s: %v", i.Metadata.Namespace, i.Metadata.Name, err)
			} else {
				log.Debugf("Set pathMode to %s", p)
				pathMode = p
			}
		}

		for _, rule := range i.Spec.Rules {
			if rule.Http == nil {
				logger.Warn("invalid ingress item: rule missing http definitions")
				continue
			}

			// it is a regexp, would be better to have exact host, needs to be added in skipper
			// this wrapping is temporary and escaping is not the right thing to do
			// currently handled as mandatory
			host := []string{"^" + strings.Replace(rule.Host, ".", "[.]", -1) + "$"}

			// update Traffic field for each backend
			computeBackendWeights(backendWeights, rule)

			for _, prule := range rule.Http.Paths {
				// add extra routes from optional annotation
				for extraIndex, r := range extraRoutes {
					route := *r
					route.HostRegexps = host
					route.Id = routeIDForCustom(
						i.Metadata.Namespace,
						i.Metadata.Name,
						route.Id,
						rule.Host+strings.Replace(prule.Path, "/", "_", -1),
						extraIndex)
					setPath(pathMode, &route, prule.Path)
					if n := countPathRoutes(&route); n <= 1 {
						hostRoutes[rule.Host] = append(hostRoutes[rule.Host], &route)
						redirect.updateHost(rule.Host)
					} else {
						log.Errorf("Failed to add route having %d path routes: %v", n, r)
					}
				}

				if prule.Backend.Traffic > 0 {
					endpointsRoute, err := c.convertPathRule(
						state,
						i.Metadata,
						rule.Host,
						prule,
						pathMode,
					)
					if err != nil {
						// if the service is not found the route should be removed
						if err == errServiceNotFound {
							continue
						}
						// Ingress status field does not support errors
						return nil, fmt.Errorf("error while getting service: %v", err)
					}

					if annotationFilter != "" {
						annotationFilters, err := eskip.ParseFilters(annotationFilter)
						if err != nil {
							logger.Errorf("Can not parse annotation filters: %v", err)
						} else {
							endpointsRoute.Filters = append(annotationFilters, endpointsRoute.Filters...)
						}
					}

					// add pre-configured default filters
					if defFilter, ok := defaultFiltersOf(prule.Backend.ServiceName, i.Metadata.Namespace, defaultFilters); ok {
						defaultFilters, err := eskip.ParseFilters(defFilter)
						if err != nil {
							logger.Errorf("Can not parse default filters: %v", err)
						} else {
							endpointsRoute.Filters = append(defaultFilters, endpointsRoute.Filters...)
						}
					}

					err = applyAnnotationPredicates(pathMode, endpointsRoute, annotationPredicate)
					if err != nil {
						logger.Errorf("failed to apply annotation predicates: %v", err)
					}

					hostRoutes[rule.Host] = append(hostRoutes[rule.Host], endpointsRoute)

					if redirect.enable || redirect.override {
						hostRoutes[rule.Host] = append(
							hostRoutes[rule.Host],
							createIngressEnableHTTPSRedirect(
								endpointsRoute,
								redirect.code,
							),
						)
						redirect.setHost(rule.Host)
					}

					if redirect.disable {
						hostRoutes[rule.Host] = append(
							hostRoutes[rule.Host],
							createIngressDisableHTTPSRedirect(
								endpointsRoute,
							),
						)
						redirect.setHostDisabled(rule.Host)
					}
				}
			}
		}

		if c.kubernetesEnableEastWest {
			for _, rule := range i.Spec.Rules {
				if rs, ok := hostRoutes[rule.Host]; ok {
					rs = append(rs, createEastWestRoutes(c.eastWestDomainRegexpPostfix, i.Metadata.Name, i.Metadata.Namespace, rs)...)
					hostRoutes[rule.Host] = rs
				}
			}
		}
	}

	for host, rs := range hostRoutes {
		if len(rs) == 0 {
			continue
		}

		routes = append(routes, rs...)

		// if routes were configured, but there is no catchall route
		// defined for the host name, create a route which returns 404
		if !catchAllRoutes(rs) {
			catchAll := &eskip.Route{
				Id:          routeID("", "catchall", host, "", ""),
				HostRegexps: rs[0].HostRegexps,
				BackendType: eskip.ShuntBackend,
			}
			routes = append(routes, catchAll)

			if c.kubernetesEnableEastWest {
				if r := createEastWestRoute(c.eastWestDomainRegexpPostfix, rs[0].Name, rs[0].Namespace, catchAll); r != nil {
					routes = append(routes, r)
				}
			}

			if code, ok := redirect.setHostCode[host]; ok {
				routes = append(routes, createIngressEnableHTTPSRedirect(catchAll, code))
			}
			if redirect.disableHost[host] {
				routes = append(routes, createIngressDisableHTTPSRedirect(catchAll))
			}
		}
	}

	return routes, nil
}

func defaultFiltersOf(service string, namespace string, defaultFilters map[resourceId]string) (string, bool) {
	if filters, ok := defaultFilters[resourceId{name: service, namespace: namespace}]; ok {
		return filters, true
	}
	return "", false
}

func createEastWestRoute(eastWestDomainRegexpPostfix, name, ns string, r *eskip.Route) *eskip.Route {
	if strings.HasPrefix(r.Id, "kubeew") || ns == "" || name == "" {
		return nil
	}
	ewR := *r
	ewR.HostRegexps = []string{"^" + name + "[.]" + ns + eastWestDomainRegexpPostfix + "$"}
	ewR.Id = patchRouteID(r.Id)
	return &ewR
}

func createEastWestRoutes(eastWestDomainRegexpPostfix, name, ns string, routes []*eskip.Route) []*eskip.Route {
	ewroutes := make([]*eskip.Route, 0)
	newHostRegexps := []string{"^" + name + "[.]" + ns + eastWestDomainRegexpPostfix + "$"}
	ingressAlreadyHandled := false

	for _, r := range routes {
		// TODO(sszuecs) we have to rethink how to handle eastwest routes in more complex cases
		n := countPathRoutes(r)
		// FIX memory leak in route creation
		if strings.HasPrefix(r.Id, "kubeew") || (n == 0 && ingressAlreadyHandled) {
			continue
		}
		r.Namespace = ns // store namespace
		r.Name = name    // store name
		ewR := *r
		ewR.HostRegexps = newHostRegexps
		ewR.Id = patchRouteID(r.Id)
		ewroutes = append(ewroutes, &ewR)
		ingressAlreadyHandled = true
	}
	return ewroutes
}

func countPathRoutes(r *eskip.Route) int {
	i := 0
	for _, p := range r.Predicates {
		if p.Name == "PathSubtree" || p.Name == "Path" {
			i++
		}
	}
	if r.Path != "" {
		i++
	}
	return i
}

// catchAllRoutes returns true if one of the routes in the list has a catchAll
// path expression.
func catchAllRoutes(routes []*eskip.Route) bool {
	for _, route := range routes {
		if len(route.PathRegexps) == 0 {
			return true
		}

		for _, exp := range route.PathRegexps {
			if exp == "^/" {
				return true
			}
		}
	}

	return false
}

// computeBackendWeights computes and sets the backend traffic weights on the
// rule backends.
// The traffic is calculated based on the following rules:
//
// * if no weight is defined for a backend it will get weight 0.
// * if no weights are specified for all backends of a path, then traffic will
//   be distributed equally.
//
// Each traffic weight is relative to the number of backends per path. If there
// are multiple backends per path the weight will be relative to the number of
// remaining backends for the path e.g. if the weight is specified as
//
//      backend-1: 0.2
//      backend-2: 0.6
//      backend-3: 0.2
//
// then the weight will be calculated to:
//
//      backend-1: 0.2
//      backend-2: 0.75
//      backend-3: 1.0
//
// where for a weight of 1.0 no Traffic predicate will be generated.
func computeBackendWeights(backendWeights map[string]float64, rule *rule) {
	type pathInfo struct {
		sum        float64
		lastActive *backend
		count      int
	}

	// get backend weight sum and count of backends for all paths
	pathInfos := make(map[string]*pathInfo)
	for _, path := range rule.Http.Paths {
		sc, ok := pathInfos[path.Path]
		if !ok {
			sc = &pathInfo{}
			pathInfos[path.Path] = sc
		}

		if weight, ok := backendWeights[path.Backend.ServiceName]; ok {
			sc.sum += weight
			if weight > 0 {
				sc.lastActive = path.Backend
			}
		} else {
			sc.count++
		}
	}

	// calculate traffic weight for each backend
	for _, path := range rule.Http.Paths {
		if sc, ok := pathInfos[path.Path]; ok {
			if weight, ok := backendWeights[path.Backend.ServiceName]; ok {
				// force a weight of 1.0 for the last backend with a non-zero weight to avoid rounding issues
				if sc.lastActive == path.Backend {
					path.Backend.Traffic = 1.0
					continue
				}

				path.Backend.Traffic = weight / sc.sum
				// subtract weight from the sum in order to
				// give subsequent backends a higher relative
				// weight.
				sc.sum -= weight
			} else if sc.sum == 0 && sc.count > 0 {
				path.Backend.Traffic = 1.0 / float64(sc.count)
			}
			// reduce count by one in order to give subsequent
			// backends for the path a higher relative weight.
			sc.count--
		}
	}
}

func mapRoutes(r []*eskip.Route) map[string]*eskip.Route {
	m := make(map[string]*eskip.Route)
	for _, ri := range r {
		m[ri.Id] = ri
	}

	return m
}

// filterIngressesByClass will filter only the ingresses that have the valid class, these are
// the defined one, empty string class or not class at all
func (c *Client) filterIngressesByClass(items []*ingressItem) []*ingressItem {
	validIngs := []*ingressItem{}

	for _, ing := range items {
		// No metadata is the same as no annotations for us
		if ing.Metadata != nil {
			cls, ok := ing.Metadata.Annotations[ingressClassKey]
			// Skip loop iteration if not valid ingress (non defined, empty or non defined one)
			if ok && cls != "" && !c.ingressClass.MatchString(cls) {
				continue
			}
		}
		validIngs = append(validIngs, ing)
	}

	return validIngs
}

func (c *Client) loadIngresses() ([]*ingressItem, error) {
	var il ingressList
	if err := c.getJSON(c.ingressesURI, &il); err != nil {
		log.Debugf("requesting all ingresses failed: %v", err)
		return nil, err
	}

	log.Debugf("all ingresses received: %d", len(il.Items))
	fItems := c.filterIngressesByClass(il.Items)
	log.Debugf("filtered ingresses by ingress class: %d", len(fItems))

	sort.Slice(fItems, func(i, j int) bool {
		mI := fItems[i].Metadata
		mJ := fItems[j].Metadata
		if mI == nil && mJ != nil {
			return true
		} else if mJ == nil {
			return false
		}
		nsI := mI.Namespace
		nsJ := mJ.Namespace
		if nsI != nsJ {
			return nsI < nsJ
		}
		return mI.Name < mJ.Name
	})

	return fItems, nil
}

func (c *Client) loadServices() (map[resourceId]*service, error) {
	var services serviceList
	if err := c.getJSON(c.servicesURI, &services); err != nil {
		log.Debugf("requesting all services failed: %v", err)
		return nil, err
	}

	log.Debugf("all services received: %d", len(services.Items))
	result := make(map[resourceId]*service)
	for _, service := range services.Items {
		result[service.Meta.toResourceId()] = service
	}
	return result, nil
}

func (c *Client) loadEndpoints() (map[resourceId]*endpoint, error) {
	var endpoints endpointList
	if err := c.getJSON(c.endpointsURI, &endpoints); err != nil {
		log.Debugf("requesting all endpoints failed: %v", err)
		return nil, err
	}

	log.Debugf("all endpoints received: %d", len(endpoints.Items))
	result := make(map[resourceId]*endpoint)
	for _, endpoint := range endpoints.Items {
		result[endpoint.Meta.toResourceId()] = endpoint
	}
	return result, nil
}

func (c *Client) fetchClusterState() (*clusterState, error) {
	ingresses, err := c.loadIngresses()
	if err != nil {
		return nil, err
	}
	services, err := c.loadServices()
	if err != nil {
		return nil, err
	}
	endpoints, err := c.loadEndpoints()
	if err != nil {
		return nil, err
	}

	return &clusterState{
		ingresses:       ingresses,
		services:        services,
		endpoints:       endpoints,
		cachedEndpoints: make(map[endpointId][]string),
	}, nil
}

func (c *Client) loadAndConvert() ([]*eskip.Route, error) {
	state, err := c.fetchClusterState()
	if err != nil {
		return nil, err
	}

	defaultFilters := c.fetchDefaultFilterConfigs()
	log.Debugf("got default filter configurations for %d services", len(defaultFilters))

	r, err := c.ingressToRoutes(state, defaultFilters)
	if err != nil {
		log.Debugf("converting ingresses to routes failed: %v", err)
		return nil, err
	}
	log.Debugf("all routes created: %d", len(r))

	return r, nil
}

func healthcheckRoute(healthy, reverseSourcePredicate bool) *eskip.Route {
	status := http.StatusOK
	if !healthy {
		status = http.StatusServiceUnavailable
	}

	var p []*eskip.Predicate
	if reverseSourcePredicate {
		p = []*eskip.Predicate{{
			Name: source.NameLast,
			Args: internalIPs,
		}}
	} else {
		p = []*eskip.Predicate{{
			Name: source.Name,
			Args: internalIPs,
		}}
	}

	return &eskip.Route{
		Id:         healthcheckRouteID,
		Predicates: p,
		Path:       healthcheckPath,
		Filters: []*eskip.Filter{{
			Name: builtin.StatusName,
			Args: []interface{}{status}},
		},
		Shunt: true,
	}
}

func (c *Client) hasReceivedTerm() bool {
	select {
	case s := <-c.sigs:
		log.Infof("shutdown, caused by %s, set health check to be unhealthy", s)
		c.termReceived = true
	default:
	}

	return c.termReceived
}

func (c *Client) LoadAll() ([]*eskip.Route, error) {
	log.Debug("loading all")
	r, err := c.loadAndConvert()
	if err != nil {
		log.Errorf("failed to load all: %v", err)
		return nil, err
	}

	// teardown handling: always healthy unless SIGTERM received
	if c.provideHealthcheck {
		c.healthy = !c.hasReceivedTerm()
		r = append(r, healthcheckRoute(c.healthy, c.reverseSourcePredicate))
	}

	if c.provideHTTPSRedirect {
		r = append(r, globalRedirectRoute(c.httpsRedirectCode))
	}

	c.current = mapRoutes(r)
	log.Debugf("all routes loaded and mapped")

	return r, nil
}

// LoadUpdate returns all known eskip.Route, a list of route IDs
// scheduled for delete and an error.
//
// TODO: implement a force reset after some time.
func (c *Client) LoadUpdate() ([]*eskip.Route, []string, error) {
	log.Debugf("polling for updates")
	r, err := c.loadAndConvert()
	if err != nil {
		log.Errorf("polling for updates failed: %v", err)
		return nil, nil, err
	}

	next := mapRoutes(r)
	log.Debugf("next version of routes loaded and mapped")

	var (
		updatedRoutes []*eskip.Route
		deletedIDs    []string
	)

	for id := range c.current {
		if r, ok := next[id]; ok && r.String() != c.current[id].String() {
			updatedRoutes = append(updatedRoutes, r)
		} else if !ok && id != healthcheckRouteID && id != httpRedirectRouteID {
			deletedIDs = append(deletedIDs, id)
		}
	}

	for id, r := range next {
		if _, ok := c.current[id]; !ok {
			updatedRoutes = append(updatedRoutes, r)
		}
	}

	if len(updatedRoutes) > 0 || len(deletedIDs) > 0 {
		log.Infof("diff taken, inserts/updates: %d, deletes: %d", len(updatedRoutes), len(deletedIDs))
	}

	// teardown handling: always healthy unless SIGTERM received
	if c.provideHealthcheck {
		healthy := !c.hasReceivedTerm()
		if healthy != c.healthy {
			c.healthy = healthy
			hc := healthcheckRoute(c.healthy, c.reverseSourcePredicate)
			next[healthcheckRouteID] = hc
			updatedRoutes = append(updatedRoutes, hc)
		}
	}

	c.current = next
	return updatedRoutes, deletedIDs, nil
}

func (c *Client) Close() {
	if c != nil && c.quit != nil {
		close(c.quit)
	}
}

func (c *Client) fetchDefaultFilterConfigs() map[resourceId]string {
	if c.defaultFiltersDir == "" {
		log.Debug("default filters are disabled")
		return make(map[resourceId]string)
	}

	filters, err := c.getDefaultFilterConfigurations()

	if err != nil {
		log.WithError(err).Error("could not fetch default filter configurations")
		return make(map[resourceId]string)
	}

	log.WithField("#configs", len(filters)).Debug("default filter configurations loaded")

	return filters
}

func (c *Client) getDefaultFilterConfigurations() (map[resourceId]string, error) {
	files, err := ioutil.ReadDir(c.defaultFiltersDir)
	if err != nil {
		return nil, err
	}

	filters := make(map[resourceId]string)
	for _, f := range files {
		r := strings.Split(f.Name(), ".") // format: {service}.{namespace}
		if len(r) != 2 || notRegularFile(f) || f.Size() > maxFileSize {
			log.WithError(err).WithField("file", f.Name()).Debug("incompatible file")
			continue
		}

		file := filepath.Join(c.defaultFiltersDir, f.Name())
		config, err := ioutil.ReadFile(file)
		if err != nil {
			log.WithError(err).WithField("file", file).Debug("could not read file")
			continue
		}

		filters[resourceId{name: r[0], namespace: r[1]}] = string(config)
	}

	return filters, nil
}

func notRegularFile(f os.FileInfo) bool {
	mode := f.Mode()
	return f.IsDir() || mode == os.ModeIrregular || mode == os.ModeDevice || mode == os.ModeNamedPipe || mode == os.ModeSocket
}

repository: AlaaAttya/skipper

repo_name: AlaaAttya/skipper


text:
package gormjqdt

import "gorm.io/gorm"

// Config defines the config for middleware.
type Config struct {
	// CaseSensitiveFilter config to determine current gormdtt using case sensitive filter.
	//
	// Optional. Default: false
	CaseSensitiveFilter bool

	// Model defines a model that using for retrive pagination resource.
	//
	// Required. Default: nil
	Model interface{}

	// Engine defines a DB engine (in this case, we using gorm) that using for build the query.
	//
	// Required. Default: nil
	Engine *gorm.DB

	// Dialect defines DB dialect that using in your app.
	//
	// Optional. Default: get dialect from connection
	Dialect string
}

// ConfigDefault is the default config
var ConfigDefault = Config{
	CaseSensitiveFilter: false,
	Model:               nil,
	Engine:              nil,
	Dialect:             "",
}

// Helper function to set default values
func configDefault(config ...Config) Config {
	// Return default config if nothing provided
	if len(config) < 1 {
		if ConfigDefault.Engine != nil {
			ConfigDefault.Dialect = ConfigDefault.Engine.Name()
		}

		return ConfigDefault
	}

	// Override default config
	cfg := config[0]

	// Set default values
	if cfg.Model == nil {
		cfg.Model = ConfigDefault.Model
	}
	if cfg.Engine == nil {
		cfg.Engine = ConfigDefault.Engine
	}
	if cfg.Dialect == "" {
		cfg.Dialect = cfg.Engine.Name()
	}

	return cfg
}

repository: or-qo/gormjqdt

repo_name: or-qo/gormjqdt


text:
/*
 * SensorCalibration.h
 *
 * Copyright (C) 2016 Cyrille Potereau
 *
 * This software may be modified and distributed under the terms
 * of the MIT license.  See the LICENSE file for details.
 */

#ifndef SENSORCALIBRATION_H_
#define SENSORCALIBRATION_H_

#include "YapiBotTypes.h"
#include "Eigen/Dense"
#include "SensorFactory.h"

typedef struct {
	double x;
	double y;
	double z;
} avgAcc_t;

class CSensorCalibration {
public:
	static void runCalibration (void);
private:
	static Eigen::MatrixXd solve(Eigen::MatrixXd & meas);
	static double partialDerivateOffset (double val, double offset, double scale);
	static double partialDerivateScale (double val, double offset, double scale);
	static void flushSensors (void);
	static void measureAndIntegrate (avgAcc_t * avgMagField, avgAcc_t * avgAngRate, avgAcc_t * avgAccel);

};

#endif /* SENSORCALIBRATION_H_ */

repository: lythaniel/YapiBot

repo_name: lythaniel/YapiBot

extension: h


text:
@article{lin_class-imbalanced_2012,
	title = {Class-imbalanced classifiers for high-dimensional data},
	issn = {1467-5463, 1477-4054},
	url = {http://bib.oxfordjournals.org/content/early/2012/03/08/bib.bbs006},
	doi = {10.1093/bib/bbs006},
	abstract = {A class-imbalanced classifier is a decision rule to predict the class membership of new samples from an available data set where the class sizes differ considerably. When the class sizes are very different, most standard classification algorithms may favor the larger (majority) class resulting in poor accuracy in the minority class prediction. A class-imbalanced classifier typically modifies a standard classifier by a correction strategy or by incorporating a new strategy in the training phase to account for differential class sizes. This article reviews and evaluates some most important methods for class prediction of high-dimensional imbalanced data. The evaluation addresses the fundamental issues of the class-imbalanced classification problem: imbalance ratio, small disjuncts and overlap complexity, lack of data and feature selection. Four class-imbalanced classifiers are considered. The four classifiers include three standard classification algorithms each coupled with an ensemble correction strategy and one support vector machines ({SVM)-based} correction classifier. The three algorithms are (i) diagonal linear discriminant analysis ({DLDA)}, (ii) random forests ({RFs)} and (ii) {SVMs.} The {SVM-based} correction classifier is {SVM} threshold adjustment ({SVM-THR).} A {Monte–Carlo} simulation and five genomic data sets were used to illustrate the analysis and address the issues. The {SVM-ensemble} classifier appears to perform the best when the class imbalance is not too severe. The {SVM-THR} performs well if the imbalance is severe and predictors are highly correlated. The {DLDA} with a feature selection can perform well without using the ensemble correction.},
	language = {en},
	urldate = {2013-09-02},
	journal = {Briefings in Bioinformatics},
	author = {Lin, Wei-Jiun and Chen, James J.},
	month = mar,
	year = {2012},
	note = {{PMID:} 22408190},
	keywords = {class-imbalanced prediction, feature selection, lack of data, performance metrics, threshold adjustment, under-sampling ensemble},
	pages = {bbs006},
	file = {Snapshot:/Users/awculott/Library/Application Support/Firefox/Profiles/0zv8dy28.default/zotero/storage/BDAQWHVI/bib.html:text/html}
}

@inproceedings{mandel12demo,
  author = {Benjamin Mandel and Aron Culotta and John Boulahanis and Danielle Stark and Bonnie Lewis and Jeremy Rodrigue},
  title = {A demographic analysis of online sentiment during {H}urricane {I}rene},
  booktitle = {NAACL-HLT Workshop on Language in Social Media},
  shortbooktitle = {HLT/NAACL},
  year = {2012},
  mytype = {Refereed Workshop Publications},
  url = {http://www2.selu.edu/Academics/Faculty/aculotta/pubs/mandel12demo.pdf},
  abstract = {We examine the response to the recent natural disaster Hurricane Irene on Twitter.com. We collect over 65,000 Twitter messages relating to Hurricane Irene from August 18th to August 31st, 2011, and group them by location and gender. We train a sentiment classifier to categorize messages based on level of concern, and then use this classifier to investigate demographic differences. We report three principal findings: (1) the number of Twitter messages related to Hurricane Irene in directly affected regions peaks around the time the hurricane hits that region; (2) the level of concern in the days leading up to the hurricane's arrival is dependent on region; and (3) the level of concern is dependent on gender, with females being more likely to express concern than males. Qualitative linguistic variations further support these differences. We conclude that social media analysis provides a viable, real-time complement to traditional survey methods for understanding public perception towards an impending disaster.},
}

@inproceedings{imran_practical_2013,
	address = {Republic and Canton of Geneva, Switzerland},
	series = {{WWW} '13 Companion},
	title = {Practical extraction of disaster-relevant information from social media},
	isbn = {978-1-4503-2038-2},
	url = {http://dl.acm.org/citation.cfm?id=2487788.2488109},
	abstract = {During times of disasters online users generate a significant amount of data, some of which are extremely valuable for relief efforts. In this paper, we study the nature of social-media content generated during two different natural disasters. We also train a model based on conditional random fields to extract valuable information from such content. We evaluate our techniques over our two datasets through a set of carefully designed experiments. We also test our methods over a non-disaster dataset to show that our extraction model is useful for extracting information from socially-generated content in general.},
	urldate = {2013-09-02},
	booktitle = {Proceedings of the 22nd international conference on World Wide Web companion},
	publisher = {International World Wide Web Conferences Steering Committee},
	author = {Imran, Muhammad and Elbassuoni, Shady and Castillo, Carlos and Diaz, Fernando and Meier, Patrick},
	year = {2013},
	keywords = {information extraction, information filtering, social media},
	pages = {1021–1024}
},

@inproceedings{meier_extracting_2013,
	title = {Extracting Information Nuggets from Disaster-Related Messages in Social Media},
	booktitle = {10th International Conference on Information Systems for Crisis Response and Management},
	author = {Meier, Patrick and Castillo, Carlos and Imran, Muhammad and Elbassuoni, Shady Mamoon and Diaz, Fernando},
	year = {2013}
},

@inproceedings{kumar_tweettracker_2011,
	title = {{TweetTracker:} An Analysis Tool for Humanitarian and Disaster Relief},
	booktitle = {{ICWSM'11}},
	author = {Kumar, Shamanth and Barbier, Geoffrey and Abbasi, Mohammad Ali and Liu, Huan},
	year = {2011}
},

@inproceedings{cheong_social_2011,
	title = {Social Media Data Mining: A Social Network Analysis Of Tweets During The 2010-2011 Australian Floods},
	booktitle = {{PACIS'11}},
	author = {Cheong, France and Cheong, Christopher},
	year = {2011},
	pages = {46--46}
}

@techreport{blei10supervised,
        type = {{arXiv} e-print},
        title = {Supervised Topic Models},
        number = {1003.0783},
        urldate = {2013-08-23},
        author = {Blei, David M. and {McAuliffe}, Jon D.},
        month = mar,
        year = {2010},
        keywords = {Statistics - Machine Learning},
}

@book{sutton12intro,
        address = {Hanover, {MA}},
        title = {An introduction to conditional random fields},
        isbn = {9781601985736  1601985738},
        url = {http://search.ebscohost.com/login.aspx?direct=true&scope=site&db=nlebk&db=nlabk&AN=593830},
        language = {English},
        urldate = {2013-08-23},
        publisher = {Now Publishers},
        author = {Sutton, Charles and {McCallum}, Andrew K},
        year = 2012
}

@article{bloom70space,
	title = {Space/time trade-offs in hash coding with allowable errors},
	volume = 13,
	issn = {0001-0782},
	url = {http://doi.acm.org/10.1145/362686.362692},
	doi = {10.1145/362686.362692},
	number = 7,
	urldate = {2013-08-23},
	journal = {Commun. {ACM}},
	author = {Bloom, Burton H.},
	month = jul,
	year = 1970,
	keywords = {hash addressing, hash coding, retrieval efficiency, retrieval trade-offs, scatter storage, searching, storage efficiency, storage layout},
	pages = {422–426}
}

@inproceedings{charikar02similarity,
	address = {New York, {NY}, {USA}},
	series = {{STOC} '02},
	title = {Similarity estimation techniques from rounding algorithms},
	isbn = {1-58113-495-9},
	url = {http://doi.acm.org/10.1145/509907.509965},
	doi = {10.1145/509907.509965},
	urldate = {2013-08-23},
	booktitle = {Proceedings of the thiry-fourth annual {ACM} symposium on Theory of computing},
	publisher = {{ACM}},
	author = {Charikar, Moses S.},
	year = 2002,
	pages = {380–388}
}

repository: dssg/tweedr

repo_name: dssg/tweedr


text:
DESCRIPTION = "A secure sockets library"
SECTION = "libs"
LICENSE = "GPL"
PR = "r1"
SRC_URI = "http://wiki.openembedded.org/dl/matrixssl-1-1-1.tar.gz \
	   file://cross.patch"
S = "${WORKDIR}/matrixssl/src"

require matrixssl.inc

CFLAGS_append = " ${@define_os(d)}"

do_install () {
	install -d ${D}${includedir}
	install -m 0644 ${S}/../matrixSsl.h ${D}${includedir}/
	oe_libinstall -so libmatrixssl ${D}${libdir}/
}

SRC_URI[md5sum] = "0f867a7b5ce70650f36caf00c4941ebf"
SRC_URI[sha256sum] = "b46ade42d080851ba4c5a10d3c520eb169fc33ab5c259ee8ca147eff57741246"

repository: overo/overo-oe-natty

repo_name: overo/overo-oe-natty

branch_name: HEAD

extension: bb


text:
package main

import (
	"fmt"
	"net"
	"os"
	"sort"
	"text/tabwriter"

	"github.com/montanaflynn/stats"
)

// AddHit to a record IP
func (r *IPRecord) AddHit() {
	r.Hits++
}

// AddElapsed to a record IP
func (r *IPRecord) AddElapsed(elapsed float64) {
	r.Elapsed = append(r.Elapsed, elapsed)
}

// RecordIP to top
func RecordIP(ip net.IP, hit int, elapsed float64) {
	TopMutex.Lock()
	defer TopMutex.Unlock()

	if _, ok := TopIP[ip.String()]; ok {
		TopIP[ip.String()].AddHit()
		TopIP[ip.String()].AddElapsed(elapsed)
	} else {
		TopIP[ip.String()] = &IPRecord{Hits: 1}
		TopIP[ip.String()].AddElapsed(elapsed)
	}
}

// IPSorted export
type IPSorted struct {
	Name       string
	ByColumn   string
	Hits       int64
	Median     float64
	Percentile float64
	Average    float64
}

func (p IPSorted) String() string {
	return fmt.Sprintf("%s", p.Name)
}

// BuildIPSorter amount of times found at the logs
type BuildIPSorter []IPSorted

func (a BuildIPSorter) Len() int      { return len(a) }
func (a BuildIPSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a BuildIPSorter) Less(i, j int) bool {

	switch a[i].ByColumn {
	case "median":
		return a[i].Median > a[j].Median
	case "percentile":
		return a[i].Percentile > a[j].Percentile
	default:
		return a[i].Hits > a[j].Hits
	}
}

// IPbyHits order by hits
func createTable(byColumn string) []IPSorted {
	ips := make([]IPSorted, len(TopIP))

	i := 0
	for k, v := range TopIP {
		hits := v.Hits
		median, _ := stats.Median(v.Elapsed)
		percentile, _ := stats.Percentile(v.Elapsed, 95)
		sum, _ := stats.Sum(v.Elapsed)
		average := sum / float64(len(v.Elapsed))

		ips[i] = IPSorted{
			Name:       k,
			Hits:       hits,
			Median:     median,
			Percentile: percentile,
			Average:    average,
			ByColumn:   byColumn,
		}
		i++
	}

	return ips
}

func printTable(ips []IPSorted, limit int) {
	w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.AlignRight|tabwriter.Debug)
	c := 0
	fmt.Fprintln(w, fmt.Sprintf("%s \t %s \t %s \t %s \t %s", "IP", "Hits", "Median latency", "Percentile 90 latency", "Average latency"))
	for _, ip := range ips {

		fmt.Fprintln(w, fmt.Sprintf("%s \t %d \t %.10f \t %.10f \t %.10f", ip.Name, ip.Hits, ip.Median, ip.Percentile, ip.Average))

		c++
		if c >= limit {
			break
		}
	}
	w.Flush()
}

// PrintBy order by byColumn (median, percentile..)
func PrintBy(limit int, byColumn string) {

	ips := createTable(byColumn)

	sort.Sort(BuildIPSorter(ips))

	printTable(ips, limit)

}

repository: APSL/go-aws-elb-log-analyzer

repo_name: APSL/go-aws-elb-log-analyzer


text:
package parser

import (
	"fmt"
	"io/ioutil"
	"regexp"
	"sort"
	"strings"

	"github.com/ystia/yorc/v4/tosca"
	"gopkg.in/yaml.v3"

	"github.com/ystia/tdt2go/internal/pkg/model"
)

type dtSlice []model.DataType

func (p dtSlice) Len() int           { return len(p) }
func (p dtSlice) Less(i, j int) bool { return p[i].FQDTN < p[j].FQDTN }
func (p dtSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }

type dtFieldsSlice []model.Field

func (p dtFieldsSlice) Len() int           { return len(p) }
func (p dtFieldsSlice) Less(i, j int) bool { return p[i].OriginalName < p[j].OriginalName }
func (p dtFieldsSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }

// Parser is the TOSCA parser used to extract model.DataType from a TOSCA definition file
type Parser struct {
	// IncludePatterns is a list of regular expression patterns that fully qualified names of TOSCA datatypes should
	// validates to be included.
	// If no patterns are provided then all datatypes are considered.
	// IncludePatterns have the precedence over ExcludePatterns.
	IncludePatterns []string
	// ExcludePatterns is a list of regular expression patterns that fully qualified names of TOSCA datatypes should
	// validates to be excluded.
	// If no patterns are provided then all datatypes are considered.
	// IncludePatterns have the precedence over ExcludePatterns.
	ExcludePatterns []string
}

func (p *Parser) nameValidatesPatterns(dtName string) (bool, error) {
	if len(p.IncludePatterns) > 0 {
		for _, i := range p.IncludePatterns {
			matched, err := regexp.MatchString(i, dtName)
			if err != nil {
				return false, fmt.Errorf("invalid include pattern %q: %w", i, err)
			}
			if matched {
				return true, nil
			}
		}
		return false, nil
	}
	if len(p.ExcludePatterns) > 0 {
		for _, e := range p.ExcludePatterns {
			matched, err := regexp.MatchString(e, dtName)
			if err != nil {
				return false, fmt.Errorf("invalid exclude pattern %q: %w", e, err)
			}
			if matched {
				return false, nil
			}
		}
	}
	return true, nil
}

// ParseTypes parses a TOSCA definition file and extracts a list of model.DataType.
//
// Only the given TOSCA file is analyzed, TOSCA imports are not taken into account.
func (p *Parser) ParseTypes(filePath string) ([]model.DataType, error) {
	topo, err := p.parseTopology(filePath)
	if err != nil {
		return nil, err
	}
	ts := make(dtSlice, 0)
	for dtName, dt := range topo.DataTypes {
		valid, err := p.nameValidatesPatterns(dtName)
		if err != nil {
			return nil, err
		}
		if !valid {
			continue
		}
		ts = append(ts, model.DataType{
			Name:        p.convertDTName(dtName),
			FQDTN:       dtName,
			DerivedFrom: p.convertTOSCAType(dt.DerivedFrom),
			Fields:      p.convertDTFields(dt.Properties),
		})
	}
	sort.Sort(ts)
	return ts, nil
}

func (p *Parser) parseTopology(filePath string) (*tosca.Topology, error) {
	b, err := ioutil.ReadFile(filePath)
	if err != nil {
		return nil, fmt.Errorf("failed to parse TOSCA definition: %w", err)
	}
	topo := &tosca.Topology{}
	err = yaml.Unmarshal(b, topo)
	if err != nil {
		return nil, fmt.Errorf("failed to parse TOSCA definition: %w", err)
	}
	return topo, nil
}

func (p *Parser) convertDTFields(props map[string]tosca.PropertyDefinition) []model.Field {
	fields := make(dtFieldsSlice, 0)
	for pName, prop := range props {
		f := model.Field{
			Name:         strings.ReplaceAll(strings.Title(strings.ReplaceAll(pName, "_", " ")), " ", ""),
			OriginalName: pName,
			Type:         p.convertDTPropType(prop),
		}
		fields = append(fields, f)
	}
	sort.Sort(fields)
	return fields
}

func (p *Parser) convertDTPropType(prop tosca.PropertyDefinition) string {
	switch strings.ToLower(prop.Type) {
	case "list":
		return "[]" + p.convertTOSCAType(prop.EntrySchema.Type)
	case "map":
		return "map[string]" + p.convertTOSCAType(prop.EntrySchema.Type)
	default:
		return p.convertTOSCAType(prop.Type)
	}
}

func (p *Parser) convertTOSCAType(t string) string {
	switch t {
	case "string":
		return "string"
	case "integer":
		return "int"
	case "boolean":
		return "bool"
	case "float":
		return "float64"
	case "timestamp":
		return "time.Time"
	case "version":
		return "Version"
	case "range":
		return "Range"
	case "scalar-unit":
		return "ScalarUnit"
	case "scalar-unit.size":
		return "ScalarUnitSize"
	case "scalar-unit.time":
		return "ScalarUnitTime"
	case "scalar-unit.frequency":
		return "ScalarUnitFrequency"
	case "scalar-unit.bitrate":
		return "ScalarUnitBitRate"
	}
	return p.convertDTName(t)
}

func (p *Parser) convertDTName(dtName string) string {
	s := strings.Split(dtName, ".")
	name := s[len(s)-1]
	name = strings.ReplaceAll(strings.Title(strings.ReplaceAll(name, "_", " ")), " ", "")
	return name
}


text:
DESCRIPTION = "TI Multiproc Manager test code"

include multiprocmgr.inc

DEPENDS = "multiprocmgr cmem"
RDEPENDS_${PN} = "multiprocmgr mpm-transport cmem"

CC += "-I${STAGING_KERNEL_DIR}/include"

do_compile() {
	make -C ${S} test
}

do_install() {
	install -d ${D}${bindir}/
	install -c -m 755 ${S}/test/filetestdemo/host/bin/demo_filetest ${D}${bindir}/mpm_demo_filetest
	install -c -m 755 ${S}/test/sync_test/host/bin/sync_test ${D}${bindir}/mpm_sync_test
}

repository: joelagnel/meta-ti

repo_name: joelagnel/meta-ti


text:
@article{sacek2017post,
  title="{Post-rift influence of small-scale convection on the landscape evolution at divergent continental margins}",
  author={Sacek, Victor},
  journal={Earth and Planetary Science Letters},
  volume={459},
  pages={48--57},
  year={2017},
  publisher={Elsevier}
}

@article{ussami1999basement,
  title="{Basement reactivation in a sub-Andean foreland flexural bulge: The Pantanal wetland, SW Brazil}",
  author={Ussami, Naomi and Shiraiwa, Shozo and Dominguez, Jos{\'e} Maria Landim},
  journal={Tectonics},
  volume={18},
  number={1},
  pages={25--39},
  year={1999},
  publisher={Wiley Online Library}
}

@article{horton1997modern,
  title="{The modern foreland basin system adjacent to the Central Andes}",
  author={Horton, Brian K. and DeCelles, Peter G.},
  journal={Geology},
  volume={25},
  number={10},
  pages={895--898},
  year={1997},
  publisher={Geological Society of America}
}

@article{assumpccao1988source,
  title="{Source mechanisms of moderate-size earthquakes and stress orientation in mid-plate South America}",
  author={Assump{\c{c}}{\~a}o, Marcelo and Su{\'a}rez, Gerardo},
  journal={Geophysical Journal International},
  volume={92},
  number={2},
  pages={253--267},
  year={1988},
  publisher={Blackwell Publishing Ltd Oxford, UK}
}

@article{pasyanos2014litho1,
  title="{LITHO1.0: An updated crust and lithospheric model of the Earth}",
  author={Pasyanos, Michael E. and Masters, T. Guy and Laske, Gabi and Ma, Zhitu},
  journal={Journal of Geophysical Research: Solid Earth},
  volume={119},
  number={3},
  pages={2153--2173},
  year={2014},
  publisher={Wiley Online Library}
}

@article{hayes2018slab2,
  title="{Slab2, a comprehensive subduction zone geometry model}",
  author={Hayes, Gavin P. and Moore, Ginevra L. and Portner, Daniel E. and Hearne, Mike and Flamme, Hanna and Furtney, Maria and Smoczyk, Gregory M.},
  journal={Science},
  volume={362},
  number={6410},
  pages={58--61},
  year={2018},
  publisher={American Association for the Advancement of Science}
}

@incollection{treatise7.05,
  Address = {Amsterdam},
  Author = {S. J. Zhong and D. A. Yuen and L. N. Moresi},
  Booktitle = "{Treatise on Geophysics, Volume 7: Mantle Dynamics}",
  Chapter = {5},
  Edition = {1},
  Editor = {David Bercovici},
  Pages = {227-252},
  Publisher = {Elsevier},
  Title = "{Numerical Methods for Mantle Convection}",
  Volume = {7},
  Year = {2007}
}

@article{solomatov2000scaling,
  title="{Scaling of time-dependent stagnant lid convection: Application to small-scale convection on Earth and other terrestrial planets}",
  author={Solomatov, V. S. and Moresi, L. N.},
  journal={Journal of Geophysical Research: Solid Earth},
  volume={105},
  number={B9},
  pages={21795--21817},
  year={2000},
  publisher={Wiley Online Library}
}

repository: jamisonassuncao/posterISAG

repo_name: jamisonassuncao/posterISAG