// -*- Mode: Go; indent-tabs-mode: t -*-

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

package sysdb

import (
	"fmt"
	"os"

	"github.com/snapcore/snapd/asserts"
)

const (
	encodedCanonicalAccount = `type: account
authority-id: canonical
account-id: canonical
display-name: Canonical
timestamp: 2016-04-01T00:00:00.0Z
username: canonical
validation: certified
sign-key-sha3-384: -CvQKAwRQ5h3Ffn10FILJoEZUXOv6km9FwA80-Rcj-f-6jadQ89VRswHNiEB9Lxk

AcLDXAQAAQoABgUCV7UYzwAKCRDUpVvql9g3IK7uH/4udqNOurx5WYVknzXdwekp0ovHCQJ0iBPw
TSFxEVr9faZSzb7eqJ1WicHsShf97PYS3ClRYAiluFsjRA8Y03kkSVJHjC+sIwGFubsnkmgflt6D
WEmYIl0UBmeaEDS8uY4Xvp9NsLTzNEj2kvzy/52gKaTc1ZSl5RDL9ppMav+0V9iBYpiDPBWH2rJ+
aDSD8Rkyygm0UscfAKyDKH4lrvZ0WkYyi1YVNPrjQ/AtBySh6Q4iJ3LifzKa9woIyAuJET/4/FPY
oirqHAfuvNod36yNQIyNqEc20AvTvZNH0PSsg4rq3DLjIPzv5KbJO9lhsasNJK1OdL6x8Yqrdsbk
ldZp4qkzfjV7VOMQKaadfcZPRaVVeJWOBnBiaukzkhoNlQi1sdCdkBB/AJHZF8QXw6c7vPDcfnCV
1lW7ddQ2p8IsJbT6LzpJu3GW/P4xhNgCjtCJ1AJm9a9RqLwQYgdLZwwDa9iCRtqTbRXBlfy3apps
1VjbQ3h5iCd0hNfwDBnGVm1rhLKHCD1DUdNE43oN2ZlE7XGyh0HFV6vKlpqoW3eoXCIxWu+HBY96
+LSl/jQgCkb0nxYyzEYK4Reb31D0mYw1Nji5W+MIF5E09+DYZoOT0UvR05YMwMEOeSdI/hLWg/5P
k+GDK+/KopMmpd4D1+jjtF7ZvqDpmAV98jJGB2F88RyVb4gcjmFFyTi4Kv6vzz/oLpbm0qrizC0W
HLGDN/ymGA5sHzEgEx7U540vz/q9VX60FKqL2YZr/DcyY9GKX5kCG4sNqIIHbcJneZ4frM99oVDu
7Jv+DIx/Di6D1ULXol2XjxbbJLKHFtHksR97ceaFvcZwTogC61IYUBJCvvMoqdXAWMhEXCr0QfQ5
Xbi31XW2d4/lF/zWlAkRnGTzufIXFni7+nEuOK0SQEzO3/WaRedK1SGOOtTDjB8/3OJeW96AUYK5
oTIynkYkEyHWMNCXALg+WQW6L4/YO7aUjZ97zOWIugd7Xy63aT3r/EHafqaY2nacOhLfkeKZ830b
o/ezjoZQAxbh6ce7JnXRgE9ELxjdAhBTpGjmmmN2sYrJ7zP9bOgly0BnEPXGSQfFA+NNNw1FADx1
MUY8q9DBjmVtgqY+1KGTV5X8KvQCBMODZIf/XJPHdCRAHxMd8COypcwgL2vDIIXpOFbi1J/B0GF+
eklxk9wzBA8AecBMCwCzIRHDNpD1oa2we38bVFrOug6e/VId1k1jYFJjiLyLCDmV8IMYwEllHSXp
LQAdm3xZ7t4WnxYC8YSCk9mXf3CZg59SpmnV5Q5Z6A5Pl7Nc3sj7hcsMBZEsOMPzNC9dPsBnZvjs
WpPUffJzEdhHBFhvYMuD4Vqj6ejUv9l3oTrjQWVC
`

	encodedCanonicalRootAccountKey = `type: account-key
authority-id: canonical
public-key-sha3-384: -CvQKAwRQ5h3Ffn10FILJoEZUXOv6km9FwA80-Rcj-f-6jadQ89VRswHNiEB9Lxk
account-id: canonical
since: 2016-04-01T00:00:00.0Z
body-length: 1406
sign-key-sha3-384: -CvQKAwRQ5h3Ffn10FILJoEZUXOv6km9FwA80-Rcj-f-6jadQ89VRswHNiEB9Lxk

AcbDTQRWhcGAASAA4Zdo3CVpKmTecjd3VDBiFbZTKKhcG0UV3FXxyGIe2UsdnJIks4NkVYO+qYk0
zW26Svpa5OIOJGO2NcgN9bpCYWZOufO1xTmC7jW/fEtqJpX8Kcq20+X5AarqJ5RBVnGLrlz+ZT99
aHdRZ4YQ2XUZvhbelzWTdK5+2eMSXNrFjO6WwGh9NRekE/NIBNwvULAtJ5nv1KwZaSpZ+klJrstU
EHPhs+NGGm1Aru01FFl3cWUm5Ao8i9y+pFcPoaRatgtpYU8mg9gP594lvyJqjFofXvHPwztmySqf
FVAp4gLLfLvRxbXkOfPUz8guidqvg6r4DUD+kCBjKYoT44PjK6l51MzEL2IEy6jdnFTgjHbaYML8
/5NpuPu8XiSjCpOTeNR+XKzXC2tHRU7j09Xd44vKRhPk0Hc4XsPNBWqfrcbdWmwsFhjfxFDJajOq
hzWVoiRc5opB5socbRjLf+gYtncxe99oC2FDA2FcftlFoyztho0bAzeFer1IHJIMYWxKMESjvJUE
pnMMKpIMYY0QfWEo5hXR0TaT+NxW2Z9Jqclgyw13y5iY72ZparHS66J+C7dxCEOswlw1ypNic6MM
/OzpafIQ10yAT3HeRCJQQOOSSTaold+WpWsQweYCywPcu9S+wCo6CrPzJCCIxOAnXjLYv2ykTJje
pNJ2+GZ1WH2UeJdJ5sR8fpxxRupqHuEKNRZ+2CqLmFC5kHNszoGolLEvGcK4BJciO4KihnKtxrdX
dUJIOPBLktA8XiiHSOmLzs2CFjcvlDuPSpe64HIL5yCxO1/GRux4A1Kht1+DqTrL7DjyIW+vIPro
A1PQwkcAJyScNRxT4bPpUj8geAXWd3n212W+7QVHuQEFezvXC5GbMyR+Xj47FOFcFcSZID1hTZEu
uMD+AxaBHQKwPfBx1arVKE1OhkuKHeSFtZRP8K8l3qj5W0sIxxIW19W8aziu8ZeDMT+nIEJrJvhx
zGEdxwCrp3k2/93oDV7g+nb1ZGfIhtmcrKziijghzPLaYaiM9LggqwTARelk3xSzd8+uk3LPXuVl
fP8/xHApss6sCE3xk4+F3OGbL7HbGuCnoulf795XKLRTy+xU/78piOMNJJQu+G0lMZIO3cZrP6io
MYDa+jDZw4V4fBRWce/FA3Ot1eIDxCq5v+vfKw+HfUlWcjm6VUQIFZYbK+Lzj6mpXn81BugG3d+M
0WNFObXIrUbhnKcYkus3TSJ9M1oMEIMp0WfFGAVTd61u36fdi2e+/xbLN0kbYcFRZwd9CmtEeDZ0
eYx/pvKKaNz/DfUr0piVCRwxuxQ0kVppklHPO4sOTFZUId8KLHg28LbszvupSsHP/nHlW8l5/VK6
4+KxRV2XofsUnwARAQAB

AcLDXAQAAQoABgUCV7UYSwAKCRDUpVvql9g3IHdDH/91mQt0ETn1VnoH/nmlbvgkpkCLkxRg6kvB
WOiEYijhfG42QV2H7mG6D2blyoYWB8Kn/T7l7qQmNHEQWXy4DKSEolQ4Mffx2nnuUglnEEwxqsT5
Wl0zydo/szWJR0LGA8XDDypLBpqKoo4x2Pfu/KiVf5Ss7LVJoLJgT6fShaChA7YWrxEuBVkUupSh
AyGvUEFCuf98hr9dehBAbodgfiDtB+7pkEMPMasyPS+bD0d2dX98Jv5aiJFgjNjTyutcf7Ekz+Bx
UavLiEtt7KmNqYnsKbdnqtXQRlkfNgPleIrETRnYBE7Dgv3OaMXbZ/X9NYTleNfJfpgnGVCeCqS5
M1MM5jcyb3lLRGQ/B0DeeIMwRmWSGplw0SC98Z5J/EUf+pP2HN68F8xGd+rWOlzJS9XU2QISlrpc
o8bW89kyBfrSox9Vo5cPLTB2vq1nS/QI6vvh7uJISIqmhZ934vK1eRl4CXp5Cyid5bgn6i85nLME
QY4KC8cO5pP9XnuKY3tN3DdPnh5AWJgjBL8DNfrKxOB/mIsL4oiHys+iF7zQWfC3ohzkOXo9Yaae
c1y11tFl3+zpzHUCqG0GemEeUl+Qnj7WFRfLv3kPDLRVBP8Z57VOXP3MRnxmvGxnyXpO7Jqu8lTE
DaZWi4N3IjCjfZaYyJK7LyMBxZvntrwNfVI/GaaXhj/u3kq3+jv6DTj8KM9Zr/qxYnu1x7u/1w+F
Rq9Z92d7zLWiuudDEQZtWCQejXVgAtaZFwv+UX50cUjby4X6G+cA0/HxFG3RAeTw8sKKcSTwCphL
o9Rbo2j+SpOl4DZkCiqabx4u8r5f9ia10fHh4JmPLOwrMUiG0dKEwCAOTk/hDh2QlsCfNr8oe5Mn
keiL8xpkaZgHr1VyMognwyq+PTILsaV3AoxwEspIBnVWw/Vzg44pIaIcXssIBT0FsvrQEz9QEMK6
UJvha6Y0iXakf9mHE12/Fv3TBMnx7QtXKE3uivAmOkD6CMSyp2vSMnI4Jz3FeyuPo35QLsA8PRcC
AQ1ex0O32bAiZC58S/rIwqGRbwDhxG7VtCmxDkjyRxkkTMV7v/51CsX/xnQSqtJZj8Ie1BkwdhjF
jhsfnYiFLT0/1q1boPkjblIwff6sYVbZhcPMIQNvtDOC0fHxULieQOxYJZvPfSYwVErHdifu8+Lh
nJozK7qeDuybkJmkKsPHPxDWO6Pij6kOZ+hwq8QTxurSB/lll0sLfKMK2rapljiyrEmM+KjrMF2V
uaHhaTjA7lX5EgbPLyUTej8joPPKGDSy9YJPTCwmYK7AOKiZAWIs3br59rPU7NvmvEnJ52S/Jhpe
eLzPgOTS4Dklh8H8OXkug2oqBuGwDG6N93ZjgkO8
`
)

var (
	trustedAssertions        []asserts.Assertion
	trustedStagingAssertions []asserts.Assertion
	trustedExtraAssertions   []asserts.Assertion
)

func init() {
	canonicalAccount, err := asserts.Decode([]byte(encodedCanonicalAccount))
	if err != nil {
		panic(fmt.Sprintf("cannot decode trusted assertion: %v", err))
	}
	canonicalRootAccountKey, err := asserts.Decode([]byte(encodedCanonicalRootAccountKey))
	if err != nil {
		panic(fmt.Sprintf("cannot decode trusted assertion: %v", err))
	}
	trustedAssertions = []asserts.Assertion{canonicalAccount, canonicalRootAccountKey}
}

// Trusted returns a copy of the current set of trusted assertions as used by Open.
func Trusted() []asserts.Assertion {
	trusted := []asserts.Assertion(nil)
	if os.Getenv("SNAPPY_USE_STAGING_STORE") != "1" {
		trusted = append(trusted, trustedAssertions...)
	} else {
		trusted = append(trusted, trustedStagingAssertions...)
	}
	trusted = append(trusted, trustedExtraAssertions...)
	return trusted
}

// InjectTrusted injects further assertions into the trusted set for Open.
// Returns a restore function to reinstate the previous set. Useful
// for tests or called globally without worrying about restoring.
func InjectTrusted(extra []asserts.Assertion) (restore func()) {
	prev := trustedExtraAssertions
	trustedExtraAssertions = make([]asserts.Assertion, len(prev)+len(extra))
	copy(trustedExtraAssertions, prev)
	copy(trustedExtraAssertions[len(prev):], extra)
	return func() {
		trustedExtraAssertions = prev
	}
}
