package tdesktop

import (
	

	
	
)

// MTPAuthorization is a Telegram Desktop storage structure which stores MTProto session info.
//
// See https://github.com/telegramdesktop/tdesktop/blob/dev/Telegram/SourceFiles/main/main_account.cpp#L359.
type MTPAuthorization struct {
	// UserID is a Telegram user ID.
	UserID uint64
	// MainDC is a main DC ID of this user.
	MainDC int
	// Key is a map of keys per DC ID.
	Keys map[int]crypto.Key // DC ID -> Key
}

// See https://github.com/telegramdesktop/tdesktop/blob/v2.9.8/Telegram/SourceFiles/storage/storage_account.cpp#L898.
func ( *tdesktopFile,  crypto.Key) (MTPAuthorization, error) {
	,  := .readArray()
	if  != nil {
		return MTPAuthorization{}, errors.Wrap(, "read encrypted data")
	}

	,  := decryptLocal(, )
	if  != nil {
		return MTPAuthorization{}, errors.Wrap(, "decrypt data")
	}
	// Skip decrypted data length (uint32).
	 = [4:]
	 := qtReader{buf: bin.Buffer{Buf: }}

	// TODO(tdakkota): support other IDs.
	var  MTPAuthorization
	if  := .deserialize(&);  != nil {
		return MTPAuthorization{}, errors.Wrap(, "deserialize MTPAuthorization")
	}
	return , 
}

func ( *qtReader,  *crypto.Key) (uint32, error) {
	,  := .readUint32()
	if  != nil {
		return 0, errors.Wrap(, "read DC ID")
	}

	if  := .consumeN([:], 256);  != nil {
		return 0, errors.Wrap(, "read auth key")
	}

	return , nil
}

func ( *MTPAuthorization) ( *qtReader) error {
	,  := .readUint32()
	if  != nil {
		return errors.Wrap(, "read dbi ID")
	}
	if  != dbiMtpAuthorization {
		return errors.Errorf("unexpected id %d", )
	}

	if  := .skip(4);  != nil {
		return errors.Wrap(, "read mainLength")
	}

	,  := .readUint32()
	if  != nil {
		return errors.Wrap(, "read legacyUserID")
	}
	,  := .readUint32()
	if  != nil {
		return errors.Wrap(, "read legacyMainDCID")
	}
	if (uint64()<<32)|uint64() == kWideIdsTag {
		,  := .readUint64()
		if  != nil {
			return errors.Wrap(, "read userID")
		}
		,  := .readUint32()
		if  != nil {
			return errors.Wrap(, "read mainDcID")
		}

		.UserID = 
		.MainDC = int()
	} else {
		.UserID = uint64()
		.MainDC = int()
	}

	,  := .readUint32()
	if  != nil {
		return errors.Wrap(, "read keys length")
	}

	if .Keys == nil {
		.Keys = make(map[int]crypto.Key, )
	}
	for  := 0;  < int(); ++ {
		var  crypto.Key
		,  := readKey(, &)
		if  != nil {
			return errors.Wrapf(, "read key %d", )
		}
		// FIXME(tdakkota): what if there is more than one session per DC?
		.Keys[int()] = 
	}

	return nil
}