#!/usr/bin/env python3

# Copyright (C) 2015 Canon Incorporated. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above
#    copyright notice, this list of conditions and the following
#    disclaimer.
# 2. Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials
#    provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

import sys
import argparse
import os

from webkitpy.common.checkout.scm.detection import SCMDetector
from webkitpy.common.host import Host
from webkitpy.common.system.filesystem import FileSystem

def usesFlatpak():
    return not os.environ.get('WEBKIT_JHBUILD') or os.environ.get('WEBKIT_JHBUILD') == '0'

def listWebKitBuildFiles(fs):
    ret = []
    if fs.isdir("WebKitBuild"):
        for build_dir in fs.listdir("WebKitBuild"):
            build_path = fs.join("WebKitBuild", build_dir)
            ret.append(build_path)
    return ret

def removeFiles(fs, l):
    for each in l:
        if fs.isdir(each):
            fs.rmtree(each)
        else:
            fs.remove(each)

# Remove all 'DerivedSources' directories inside 'WebKitBuild'.
# Also remove '.ninja' files to force re-generation.
def removeDerivedSources(fs):
    derived_sources = []
    ninja_files = []
    for root, dirs, files in os.walk("WebKitBuild"):
        for dirname in dirs:
            if dirname == 'DerivedSources':
                derived_sources.append(os.path.join(root, dirname))
        for filename in files:
            # Don't remove build.ninja file for COG
            if filename.endswith(".ninja") and root.find("cog") == -1:
                path = os.path.join(root, filename)
                ninja_files.append(path)
    for each in derived_sources:
        if fs.isdir(each):
            fs.rmtree(each)
    for each in ninja_files:
        if fs.isfile(each):
            fs.remove(each)

def main(args):
    fs = FileSystem()
    host = Host()

    if args.derived_sources_only:
        removeDerivedSources(fs)
        return

    scm = SCMDetector(fs, host.executive).detect_scm_system(fs.getcwd())
    scm.discard_working_directory_changes()
    if args.optimize_local_repository:
        scm.cleanup_and_optimize_local_repository()

    if args.keep_jhbuild_directory:
        # Clean everything inside WebKitBuild, except the JHBuild directories.
        scm.discard_untracked_files(discard_ignored_files=True, keep_webkitbuild_directory=True)
        if fs.isdir("WebKitBuild"):
            files = listWebKitBuildFiles(fs)
            keepDirs = usesFlatpak() and ["Toolchains", "UserFlatpak"] or ["DependenciesGTK", "DependenciesWPE"]
            files = [path for path in files if path[len("WebKitBuild/"):] not in keepDirs]
            removeFiles(fs, files)
    else:
        scm.discard_untracked_files(discard_ignored_files=True)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Clean WebKit")
    parser.add_argument("--keep-jhbuild-directory", action="store_true",
                        help="Don't wipe the JHBuild build directories.")
    parser.add_argument('--optimize-local-repository', action='store_true',
                        default=False, help='run `git gc`')
    parser.add_argument('--derived-sources-only', action='store_true',
                        default=False, help="Delete only 'DerivedSources' directories")
    args = parser.parse_args()
    sys.exit(main(args))
