import json
import fnmatch
from pathlib import Path


def cmpmanifests(manifest_path_1, manifest_path_2, patterns=None, ignore=None):
  """Bit-accuracy test between two manifests.
  Their format is {filepath: {md5, size_st}}"""
  with manifest_path_1.open() as f:
    manifest_1 = json.load(f)
  with manifest_path_2.open() as f:
    manifest_2 = json.load(f)
  # print(manifest_1)
  # print(manifest_2)
  # print(set(manifest_1.keys()) & set(manifest_2.keys()))

  if not patterns:
    patterns = ['*']
  if not ignore:
    ignore = []

  # print(patterns)

  mismatch = set()  # not the same
  match = set()     # the same
  only_in_1 = set() # exists in dir_1 but not in dir_1
  errors = set()    # or errors accessing

  for pattern in patterns:
    pattern = f'*{pattern}'
    for file_1_str, meta_1 in manifest_1.items():
      if not fnmatch.fnmatch(file_1_str, pattern):
        continue
      file_1 = Path(file_1_str)
      if any(fnmatch.fnmatch(file_1.name, i) for i in ignore):
        continue
      if file_1_str in manifest_2:
        is_same = meta_1['md5'] == manifest_2[file_1_str]['md5']
        if not is_same:
          mismatch.add(file_1)
        else:
          match.add(file_1)
      else:
        only_in_1.add(file_1)

  return {
    "mismatch": list(mismatch),
    "match": list(match),
    "only_in_1": list(only_in_1),
    "errors": list(errors),
  }