package telegram

import (
	
	

	

	

	
	
	
	
	
)

func ( *Client) ( context.Context) error {
	if .storage == nil {
		return nil
	}

	,  := .storage.Load()
	if errors.Is(, session.ErrNotFound) {
		return nil
	}
	if  != nil {
		return errors.Wrap(, "load")
	}

	// If file does not contain DC ID, so we use DC from options.
	 := .session.Load()
	if .DC == 0 {
		.DC = .DC
	}

	// Restoring persisted auth key.
	var  crypto.AuthKey
	copy(.Value[:], .AuthKey)
	copy(.ID[:], .AuthKeyID)

	if .Value.ID() != .ID {
		return errors.New("corrupted key")
	}

	// Re-initializing connection from persisted state.
	.log.Info(, "Connection restored from state",
		log.String("addr", .Addr),
		log.String("key_id", fmt.Sprintf("%x", .AuthKeyID)),
	)

	.connMux.Lock()
	.session.Store(pool.Session{
		DC:      .DC,
		AuthKey: ,
		Salt:    .Salt,
	})
	.replaceConn(.createPrimaryConn(nil))
	.connMux.Unlock()

	return nil
}

func ( *Client) ( tg.Config,  mtproto.Session) error {
	if .storage == nil {
		return nil
	}

	,  := .storage.Load(.ctx)
	if errors.Is(, session.ErrNotFound) {
		// Initializing new state.
		 = nil
		 = &session.Data{}
	}
	if  != nil {
		return errors.Wrap(, "load")
	}

	// Updating previous data.
	.Config = session.ConfigFromTG()
	 := .Key
	if !.PermKey.Zero() {
		// Persist permanent key in PFS mode: temporary key is expected to rotate.
		 = .PermKey
	}
	.AuthKey = .Value[:]
	.AuthKeyID = .ID[:]
	.DC = .ThisDC
	.Salt = .Salt

	if  := .storage.Save(.ctx, );  != nil {
		return errors.Wrap(, "save")
	}

	.log.Debug(.ctx, "Data saved",
		log.String("key_id", fmt.Sprintf("%x", .AuthKeyID)),
	)
	return nil
}

func ( *Client) ( tg.Config,  mtproto.Session) error {
	 := dcSessionFromMTProto(.ThisDC, )
	// Track per-DC session in memory for pool reconnections/migrations.
	.storeDCSess(.sessions, )

	 := .session.Load().DC
	// Do not save session for non-primary DC.
	if .ThisDC != 0 &&  != 0 &&  != .ThisDC {
		return nil
	}

	.connMux.Lock()
	.session.Store()
	.cfg.Store()
	.onReady()
	.connMux.Unlock()

	if  := .saveSession(, );  != nil {
		return errors.Wrap(, "save")
	}

	return nil
}

func ( *Client) ( tg.Config,  mtproto.Session) error {
	// CDN sessions are isolated from regular DC map because lifecycle and reset
	// triggers differ (fingerprint misses, CDN-specific reconnects).
	.storeDCSess(.cdnSessions, dcSessionFromMTProto(.ThisDC, ))
	return nil
}

func ( *Client) ( map[int]*pool.SyncSession,  pool.Session) {
	.sessionsMux.Lock()
	if ,  := [.DC];  {
		.Store()
		.sessionsMux.Unlock()
		return
	}
	[.DC] = pool.NewSyncSession()
	.sessionsMux.Unlock()
}

func ( int,  mtproto.Session) pool.Session {
	 := .Key
	if !.PermKey.Zero() {
		// Keep in-memory/persisted key format backward-compatible: one key slot.
		// In PFS mode temp key rotates, so we pin permanent key.
		 = .PermKey
	}

	return pool.Session{
		DC:      ,
		Salt:    .Salt,
		AuthKey: ,
	}
}