import*as Common from"../../../core/common/common.js";import*as LitHtml from"../../lit-html/lit-html.js";import*as ComponentHelpers from"../helpers/helpers.js";import linearMemoryInspectorStyles from"./linearMemoryInspector.css.js";const{render:render,html:html}=LitHtml;import{LinearMemoryNavigator}from"./LinearMemoryNavigator.js";import{LinearMemoryValueInterpreter}from"./LinearMemoryValueInterpreter.js";import{VALUE_INTEPRETER_MAX_NUM_BYTES,getDefaultValueTypeMapping}from"./ValueInterpreterDisplayUtils.js";import{formatAddress,parseAddress}from"./LinearMemoryInspectorUtils.js";import{LinearMemoryViewer}from"./LinearMemoryViewer.js";import{LinearMemoryHighlightChipList}from"./LinearMemoryHighlightChipList.js";import*as i18n from"../../../core/i18n/i18n.js";const UIStrings={addressHasToBeANumberBetweenSAnd:"Address has to be a number between {PH1} and {PH2}"},str_=i18n.i18n.registerUIStrings("ui/components/linear_memory_inspector/LinearMemoryInspector.ts",UIStrings),i18nString=i18n.i18n.getLocalizedString.bind(void 0,str_);export class MemoryRequestEvent extends Event{static eventName="memoryrequest";data;constructor(e,t,s){super(MemoryRequestEvent.eventName),this.data={start:e,end:t,address:s}}}export class AddressChangedEvent extends Event{static eventName="addresschanged";data;constructor(e){super(AddressChangedEvent.eventName),this.data=e}}export class SettingsChangedEvent extends Event{static eventName="settingschanged";data;constructor(e){super(SettingsChangedEvent.eventName),this.data=e}}class AddressHistoryEntry{#e=0;#t;constructor(e,t){if(e<0)throw new Error("Address should be a greater or equal to zero");this.#e=e,this.#t=t}valid(){return!0}reveal(){this.#t(this.#e)}}export class LinearMemoryInspector extends HTMLElement{static litTagName=LitHtml.literal`devtools-linear-memory-inspector-inspector`;#s=this.attachShadow({mode:"open"});#r=new Common.SimpleHistoryManager.SimpleHistoryManager(10);#i=new Uint8Array;#a=0;#o=0;#e=-1;#n;#d="Submitted";#h=`${this.#e}`;#m=4;#g=getDefaultValueTypeMapping();#l=new Set(this.#g.keys());#y="Little Endian";connectedCallback(){this.#s.adoptedStyleSheets=[linearMemoryInspectorStyles]}set data(e){if(e.address<e.memoryOffset||e.address>e.memoryOffset+e.memory.length||e.address<0)throw new Error("Address is out of bounds.");if(e.memoryOffset<0)throw new Error("Memory offset has to be greater or equal to zero.");if(e.highlightInfo){if(e.highlightInfo.size<0)throw new Error("Object size has to be greater than or equal to zero");if(e.highlightInfo.startAddress<0||e.highlightInfo.startAddress>=e.outerMemoryLength)throw new Error("Object start address is out of bounds.")}this.#i=e.memory,this.#a=e.memoryOffset,this.#o=e.outerMemoryLength,this.#g=e.valueTypeModes||this.#g,this.#l=e.valueTypes||this.#l,this.#y=e.endianness||this.#y,this.#n=e.highlightInfo,this.#u(e.address),this.#p()}#p(){const{start:e,end:t}=this.#c(this.#e,this.#m),s="Submitted"===this.#d?formatAddress(this.#e):this.#h,r=this.#v(s),i=i18nString(UIStrings.addressHasToBeANumberBetweenSAnd,{PH1:formatAddress(0),PH2:formatAddress(this.#o)}),a=r?void 0:i,o=this.#r.canRollback(),n=this.#r.canRollover(),d=this.#n?[this.#n]:[],h=this.#M(d,this.#e);render(html`
      <div class="view">
        <${LinearMemoryNavigator.litTagName}
          .data=${{address:s,valid:r,mode:this.#d,error:a,canGoBackInHistory:o,canGoForwardInHistory:n}}
          @refreshrequested=${this.#f}
          @addressinputchanged=${this.#T}
          @pagenavigation=${this.#A}
          @historynavigation=${this.#L}></${LinearMemoryNavigator.litTagName}>
          <${LinearMemoryHighlightChipList.litTagName}
          .data=${{highlightInfos:d,focusedMemoryHighlight:h}}
          @jumptohighlightedmemory=${this.#E}>
          </${LinearMemoryHighlightChipList.litTagName}>
        <${LinearMemoryViewer.litTagName}
          .data=${{memory:this.#i.slice(e-this.#a,t-this.#a),address:this.#e,memoryOffset:e,focus:"Submitted"===this.#d,highlightInfo:this.#n,focusedMemoryHighlight:h}}
          @byteselected=${this.#S}
          @resize=${this.#w}>
        </${LinearMemoryViewer.litTagName}>
      </div>
      <div class="value-interpreter">
        <${LinearMemoryValueInterpreter.litTagName}
          .data=${{value:this.#i.slice(this.#e-this.#a,this.#e+VALUE_INTEPRETER_MAX_NUM_BYTES).buffer,valueTypes:this.#l,valueTypeModes:this.#g,endianness:this.#y,memoryLength:this.#o}}
          @valuetypetoggled=${this.#N}
          @valuetypemodechanged=${this.#I}
          @endiannesschanged=${this.#b}
          @jumptopointeraddress=${this.#E}
          >
        </${LinearMemoryValueInterpreter.litTagName}/>
      </div>
      `,this.#s,{host:this})}#E(e){e.stopPropagation(),this.#d="Submitted";const t=Math.max(0,Math.min(e.data,this.#o-1));this.#H(t)}#f(){const{start:e,end:t}=this.#c(this.#e,this.#m);this.dispatchEvent(new MemoryRequestEvent(e,t,this.#e))}#S(e){this.#d="Submitted";const t=Math.max(0,Math.min(e.data,this.#o-1));this.#H(t)}#P(){return{valueTypes:this.#l,modes:this.#g,endianness:this.#y}}#b(e){this.#y=e.data,this.dispatchEvent(new SettingsChangedEvent(this.#P())),this.#p()}#v(e){const t=parseAddress(e);return void 0!==t&&t>=0&&t<this.#o}#T(e){const{address:t,mode:s}=e.data,r=this.#v(t),i=parseAddress(t);if(this.#h=t,void 0!==i&&r)return this.#d=s,void this.#H(i);this.#d="Submitted"!==s||r?"Edit":"InvalidSubmit",this.#p()}#N(e){const{type:t,checked:s}=e.data;s?this.#l.add(t):this.#l.delete(t),this.dispatchEvent(new SettingsChangedEvent(this.#P())),this.#p()}#I(e){e.stopImmediatePropagation();const{type:t,mode:s}=e.data;this.#g.set(t,s),this.dispatchEvent(new SettingsChangedEvent(this.#P())),this.#p()}#L(e){return"Forward"===e.data?this.#r.rollover():this.#r.rollback()}#A(e){const t="Forward"===e.data?this.#e+this.#m:this.#e-this.#m,s=Math.max(0,Math.min(t,this.#o-1));this.#H(s)}#H(e){e<0||e>=this.#o?console.warn(`Specified address is out of bounds: ${e}`):(this.#u(e),this.#C())}#c(e,t){const s=Math.floor(e/t)*t;return{start:s,end:Math.min(s+t,this.#o)}}#w(e){this.#m=e.data,this.#C()}#C(){const{start:e,end:t}=this.#c(this.#e,this.#m);e<this.#a||t>this.#a+this.#i.length?this.dispatchEvent(new MemoryRequestEvent(e,t,this.#e)):this.#p()}#u(e){if(this.#e===e)return;const t=new AddressHistoryEntry(e,(()=>this.#H(e)));this.#r.push(t),this.#e=e,this.dispatchEvent(new AddressChangedEvent(this.#e))}#M(e,t){let s;for(const r of e)r.startAddress<=t&&t<r.startAddress+r.size&&(s?r.size<s.size&&(s=r):s=r);return s}}ComponentHelpers.CustomElements.defineComponent("devtools-linear-memory-inspector-inspector",LinearMemoryInspector);