// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.android.ziputils;

import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;

import java.nio.ByteBuffer;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Unit tests for {@link ScanUtil}.
 */
@RunWith(JUnit4.class)
public class ScanUtilTest {

  @Test
  public void testScanTo() {
    assertThrows(NullPointerException.class, () -> assertLocation(null, new byte[] {}, -1));
    assertThrows(NullPointerException.class, () -> assertLocation(new byte[] {}, null, -1));
    assertLocation(new byte[] {}, new byte[] {}, -1);
    assertLocation(new byte[] {}, new byte[] {1}, 0);
    assertLocation(new byte[] {}, new byte[] {1, 2, 3, 4}, 0);
    assertLocation(new byte[] {1}, new byte[] {}, -1);
    assertLocation(new byte[] {1}, new byte[] {1}, 0);
    assertLocation(new byte[] {1}, new byte[] {1, 2, 3, 4}, 0);
    assertLocation(new byte[] {1}, new byte[] {5, 4, 1, 2, 3, 4}, 2);
    assertLocation(new byte[] {1}, new byte[] {4, 2, 3, 1}, 3);
    assertLocation(new byte[] {1, 2, 3, 4}, new byte[] {}, -1);
    assertLocation(new byte[] {1, 2, 3, 4}, new byte[] {1}, -1);
    assertLocation(new byte[] {1, 2, 3, 4}, new byte[] {1, 2, 3, 4}, 0);
    assertLocation(new byte[] {1, 2, 3, 4}, new byte[] {1, 2, 3, 4, 1, 2, 3, 4}, 0);
    assertLocation(new byte[] {1, 2, 3, 4}, new byte[] {5, 1, 2, 3, 4}, 1);
    assertLocation(new byte[] {1, 2, 3, 4}, new byte[] {5, 1, 2, 3, 4, 5}, 1);
    assertLocation(new byte[] {1, 2, 3, 4}, new byte[] {5, 5, 1, 2, 3, 4}, 2);
    assertLocation(new byte[] {1, 2, 3, 4}, new byte[] {5, 1, 1, 2, 3, 4}, 2);
    assertLocation(new byte[] {1, 2, 3, 4}, new byte[] {5, 1, 2, 3, 5, 4}, -1);
  }

  @Test
  public void testScanBackwardsTo() {
    assertThrows(
        NullPointerException.class, () -> assertBackwardsLocation(null, new byte[] {}, -1));
    assertThrows(
        NullPointerException.class, () -> assertBackwardsLocation(new byte[] {}, null, -1));
    assertBackwardsLocation(new byte[] {}, new byte[] {}, -1);
    assertBackwardsLocation(new byte[] {}, new byte[] {1}, 0);
    assertBackwardsLocation(new byte[] {}, new byte[] {1, 2, 3, 4}, 3);
    assertBackwardsLocation(new byte[] {1}, new byte[] {}, -1);
    assertBackwardsLocation(new byte[] {1}, new byte[] {1}, 0);
    assertBackwardsLocation(new byte[] {1}, new byte[] {1, 2, 3, 4}, 0);
    assertBackwardsLocation(new byte[] {1}, new byte[] {5, 4, 1, 2, 3, 4}, 2);
    assertBackwardsLocation(new byte[] {1}, new byte[] {4, 2, 3, 1}, 3);
    assertBackwardsLocation(new byte[] {1, 2, 3, 4}, new byte[] {}, -1);
    assertBackwardsLocation(new byte[] {1, 2, 3, 4}, new byte[] {1}, -1);
    assertBackwardsLocation(new byte[] {1, 2, 3, 4}, new byte[] {1, 2, 3, 4}, 0);
    assertBackwardsLocation(new byte[] {1, 2, 3, 4}, new byte[] {1, 2, 3, 4, 1, 2, 3, 4}, 4);
    assertBackwardsLocation(new byte[] {1, 2, 3, 4}, new byte[] {1, 2, 3, 4, 1, 2, 3, 4, 1}, 4);
    assertBackwardsLocation(new byte[] {1, 2, 3, 4}, new byte[] {5, 1, 2, 3, 4}, 1);
    assertBackwardsLocation(new byte[] {1, 2, 3, 4}, new byte[] {5, 1, 2, 3, 4, 5}, 1);
    assertBackwardsLocation(new byte[] {1, 2, 3, 4}, new byte[] {5, 5, 1, 2, 3, 4}, 2);
    assertBackwardsLocation(new byte[] {1, 2, 3, 4}, new byte[] {5, 1, 1, 2, 3, 4}, 2);
    assertBackwardsLocation(new byte[] {1, 2, 3, 4}, new byte[] {5, 1, 2, 3, 5, 4}, -1);
  }

  private void assertLocation(byte[] target, byte[] domain, int expected) {
    int pos = ScanUtil.scanTo(target, domain != null ? ByteBuffer.wrap(domain) : null);
    assertWithMessage("Position of " + Arrays.toString(target) + " in " + Arrays.toString(domain))
        .that(expected).isEqualTo(pos);
  }

  private void assertBackwardsLocation(byte[] target, byte[] domain, int expected) {
    ByteBuffer buf = null;
    if (domain != null) {
      buf = ByteBuffer.wrap(domain);
      buf.position(buf.limit());
    }
    int pos = ScanUtil.scanBackwardsTo(target, buf);
    assertWithMessage("Position of " + Arrays.toString(target) + " in " + Arrays.toString(domain)
        + ", " + buf.position() + ", " + buf.limit())
        .that(expected).isEqualTo(pos);
  }
}
