import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
import BN from "bn.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
import * as types from "../types"; // eslint-disable-line @typescript-eslint/no-unused-vars
import * as borsh from "@coral-xyz/borsh";

export interface TokenInfoFields {
  mint: PublicKey;
  decimals: BN;
  padding: Array<BN>;
}

export interface TokenInfoJSON {
  mint: string;
  decimals: string;
  padding: Array<string>;
}

export class TokenInfo {
  readonly mint: PublicKey;
  readonly decimals: BN;
  readonly padding: Array<BN>;

  constructor(fields: TokenInfoFields) {
    this.mint = fields.mint;
    this.decimals = fields.decimals;
    this.padding = fields.padding;
  }

  static layout(property?: string) {
    return borsh.struct(
      [
        borsh.publicKey("mint"),
        borsh.u64("decimals"),
        borsh.array(borsh.u64(), 10, "padding"),
      ],
      property,
    );
  }

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  static fromDecoded(obj: any) {
    return new TokenInfo({
      mint: obj.mint,
      decimals: obj.decimals,
      padding: obj.padding,
    });
  }

  static toEncodable(fields: TokenInfoFields) {
    return {
      mint: fields.mint,
      decimals: fields.decimals,
      padding: fields.padding,
    };
  }

  toJSON(): TokenInfoJSON {
    return {
      mint: this.mint.toString(),
      decimals: this.decimals.toString(),
      padding: this.padding.map((item) => item.toString()),
    };
  }

  static fromJSON(obj: TokenInfoJSON): TokenInfo {
    return new TokenInfo({
      mint: new PublicKey(obj.mint),
      decimals: new BN(obj.decimals),
      padding: obj.padding.map((item) => new BN(item)),
    });
  }

  toEncodable() {
    return TokenInfo.toEncodable(this);
  }
}
