require "arr-pm/namespace"

class ArrPM::V2::Tag
  module Type
    NULL = 0
    CHAR = 1
    INT8 = 2
    INT16 = 3
    INT32 = 4
    INT64 = 5
    STRING = 6
    BINARY = 7
    STRING_ARRAY = 8
    I18NSTRING = 9

    TYPE_MAP = Hash[constants.collect { |c| [const_get(c), c] }]

    def self.parse(data, type, offset, count)
      case type
        when NULL
          nil
        when CHAR
          data[offset, count].unpack("A#{count}")
        when INT8
          data[offset, count].unpack("C" * count)
        when INT16
          data[offset, 2 * count].unpack("n" * count)
        when INT32
          data[offset, 4 * count].unpack("N" * count)
        when INT64
          a, b = data[offset, 8].unpack("NN")
          a << 32 + b
        when STRING, I18NSTRING
          data[offset..-1][/^[^\0]*/]
        when BINARY
          data[offset, count]
        when STRING_ARRAY
          data[offset..-1].split("\0")[0...count]
        else
          raise ArrPM::V2::Error::InvalidType, type
      end
    end
  end # module Type

  HEADERIMAGE = 61
  HEADERSIGNATURES = 62
  HEADERIMMUTABLE = 63
  HEADERREGIONS = 64
  HEADERI18NTABLE = 100
  SIG_BASE = 256

  SIGSIZE = 257
  SIGLEMD5_1 = 258
  SIGPGP = 259
  SIGLEMD5_2 = 260
  SIGMD5 = 261
  SIGGPG = 262
  SIGPGP5 = 263
  BADSHA1_1 = 264
  BADSHA1_2 = 265
  PUBKEYS = 266
  DSAHEADER = 267
  RSAHEADER = 268
  SHA1HEADER = 269
  LONGSIGSIZE = 270
  LONGARCHIVESIZE = 271

  NAME = 1000
  VERSION = 1001
  RELEASE = 1002
  EPOCH = 1003
  SUMMARY = 1004
  DESCRIPTION = 1005
  BUILDTIME = 1006
  BUILDHOST = 1007
  INSTALLTIME = 1008
  SIZE = 1009
  DISTRIBUTION = 1010
  VENDOR = 1011
  GIF = 1012
  XPM = 1013
  LICENSE = 1014
  PACKAGER = 1015
  GROUP = 1016
  CHANGELOG = 1017
  SOURCE = 1018
  PATCH = 1019
  URL = 1020
  OS = 1021
  ARCH = 1022
  PREIN = 1023
  POSTIN = 1024
  PREUN = 1025
  POSTUN = 1026
  OLDFILENAMES = 1027
  FILESIZES = 1028
  FILESTATES = 1029
  FILEMODES = 1030
  FILEUIDS = 1031
  FILEGIDS = 1032
  FILERDEVS = 1033
  FILEMTIMES = 1034
  FILEDIGESTS = 1035
  FILELINKTOS = 1036
  FILEFLAGS = 1037
  ROOT = 1038
  FILEUSERNAME = 1039
  FILEGROUPNAME = 1040
  EXCLUDE = 1041
  EXCLUSIVE = 1042
  ICON = 1043
  SOURCERPM = 1044
  FILEVERIFYFLAGS = 1045
  ARCHIVESIZE = 1046
  PROVIDENAME = 1047
  REQUIREFLAGS = 1048
  REQUIRENAME = 1049
  REQUIREVERSION = 1050
  NOSOURCE = 1051
  NOPATCH = 1052
  CONFLICTFLAGS = 1053
  CONFLICTNAME = 1054
  CONFLICTVERSION = 1055
  DEFAULTPREFIX = 1056
  BUILDROOT = 1057
  INSTALLPREFIX = 1058
  EXCLUDEARCH = 1059
  EXCLUDEOS = 1060
  EXCLUSIVEARCH = 1061
  EXCLUSIVEOS = 1062
  AUTOREQPROV = 1063
  RPMVERSION = 1064
  TRIGGERSCRIPTS = 1065
  TRIGGERNAME = 1066
  TRIGGERVERSION = 1067
  TRIGGERFLAGS = 1068
  TRIGGERINDEX = 1069
  VERIFYSCRIPT = 1079
  CHANGELOGTIME = 1080
  CHANGELOGNAME = 1081
  CHANGELOGTEXT = 1082
  BROKENMD5 = 1083
  PREREQ = 1084
  PREINPROG = 1085
  POSTINPROG = 1086
  PREUNPROG = 1087
  POSTUNPROG = 1088
  BUILDARCHS = 1089
  OBSOLETENAME = 1090
  VERIFYSCRIPTPROG = 1091
  TRIGGERSCRIPTPROG = 1092
  DOCDIR = 1093
  COOKIE = 1094
  FILEDEVICES = 1095
  FILEINODES = 1096
  FILELANGS = 1097
  PREFIXES = 1098
  INSTPREFIXES = 1099
  TRIGGERIN = 1100
  TRIGGERUN = 1101
  TRIGGERPOSTUN = 1102
  AUTOREQ = 1103
  AUTOPROV = 1104
  CAPABILITY = 1105
  SOURCEPACKAGE = 1106
  OLDORIGFILENAMES = 1107
  BUILDPREREQ = 1108
  BUILDREQUIRES = 1109
  BUILDCONFLICTS = 1110
  BUILDMACROS = 1111
  PROVIDEFLAGS = 1112
  PROVIDEVERSION = 1113
  OBSOLETEFLAGS = 1114
  OBSOLETEVERSION = 1115
  DIRINDEXES = 1116
  BASENAMES = 1117
  DIRNAMES = 1118
  ORIGDIRINDEXES = 1119
  ORIGBASENAMES = 1120
  ORIGDIRNAMES = 1121
  OPTFLAGS = 1122
  DISTURL = 1123
  PAYLOADFORMAT = 1124
  PAYLOADCOMPRESSOR = 1125
  PAYLOADFLAGS = 1126
  INSTALLCOLOR = 1127
  INSTALLTID = 1128
  REMOVETID = 1129
  SHA1RHN = 1130
  RHNPLATFORM = 1131
  PLATFORM = 1132
  PATCHESNAME = 1133
  PATCHESFLAGS = 1134
  PATCHESVERSION = 1135
  CACHECTIME = 1136
  CACHEPKGPATH = 1137
  CACHEPKGSIZE = 1138
  CACHEPKGMTIME = 1139
  FILECOLORS = 1140
  FILECLASS = 1141
  CLASSDICT = 1142
  FILEDEPENDSX = 1143
  FILEDEPENDSN = 1144
  DEPENDSDICT = 1145
  SOURCEPKGID = 1146
  FILECONTEXTS = 1147
  FSCONTEXTS = 1148
  RECONTEXTS = 1149
  POLICIES = 1150
  PRETRANS = 1151
  POSTTRANS = 1152
  PRETRANSPROG = 1153
  POSTTRANSPROG = 1154
  DISTTAG = 1155
  SUGGESTSNAME = 1156
  SUGGESTSVERSION = 1157
  SUGGESTSFLAGS = 1158
  ENHANCESNAME = 1159
  ENHANCESVERSION = 1160
  ENHANCESFLAGS = 1161
  PRIORITY = 1162
  CVSID = 1163
  BLINKPKGID = 1164
  BLINKHDRID = 1165
  BLINKNEVRA = 1166
  FLINKPKGID = 1167
  FLINKHDRID = 1168
  FLINKNEVRA = 1169
  PACKAGEORIGIN = 1170
  TRIGGERPREIN = 1171
  BUILDSUGGESTS = 1172
  BUILDENHANCES = 1173
  SCRIPTSTATES = 1174
  SCRIPTMETRICS = 1175
  BUILDCPUCLOCK = 1176
  FILEDIGESTALGOS = 1177
  VARIANTS = 1178
  XMAJOR = 1179
  XMINOR = 1180
  REPOTAG = 1181
  KEYWORDS = 1182
  BUILDPLATFORMS = 1183
  PACKAGECOLOR = 1184
  PACKAGEPREFCOLOR = 1185
  XATTRSDICT = 1186
  FILEXATTRSX = 1187
  DEPATTRSDICT = 1188
  CONFLICTATTRSX = 1189
  OBSOLETEATTRSX = 1190
  PROVIDEATTRSX = 1191
  REQUIREATTRSX = 1192
  BUILDPROVIDES = 1193
  BUILDOBSOLETES = 1194
  DBINSTANCE = 1195
  NVRA = 1196
  FILENAMES = 5000
  FILEPROVIDE = 5001
  FILEREQUIRE = 5002
  FSNAMES = 5003
  FSSIZES = 5004
  TRIGGERCONDS = 5005
  TRIGGERTYPE = 5006
  ORIGFILENAMES = 5007
  LONGFILESIZES = 5008
  LONGSIZE = 5009
  FILECAPS = 5010
  FILEDIGESTALGO = 5011
  BUGURL = 5012
  EVR = 5013
  NVR = 5014
  NEVR = 5015
  NEVRA = 5016
  HEADERCOLOR = 5017
  VERBOSE = 5018
  EPOCHNUM = 5019
  ENCODING = 5062

  TAG_MAP = Hash[constants.collect { |c| [const_get(c), c] }]

  attr_accessor :tag, :type, :value

  def initialize(tag_number, type_number)
    @tag = self.class::TAG_MAP[tag_number] || tag_number
    @type = type_number
  end

  def parse(data, offset, count)
    @value = Type.parse(data, @type, offset, count)
    nil
  end

  def inspect
    format("<%s#%s> %s/%d value=%s>", self.class.name, self.object_id, @tag, @type, @value.inspect)
  end
end # module ArrPM::V2::Tag
